clang: lib/CodeGen/CGExprCXX.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
22#include "llvm/IR/Intrinsics.h"
23
24using namespace clang;
26
27namespace {
28struct MemberCallInfo {
29 RequiredArgs ReqArgs;
30
31 unsigned PrefixSize;
32};
33}
34
35static MemberCallInfo
37 llvm::Value *This, llvm::Value *ImplicitParam,
41
44 assert(MD->isImplicitObjectMemberFunction() &&
45 "Trying to emit a member or operator call expr on a static method!");
46
47
51
52
53 if (ImplicitParam) {
54 Args.add(RValue::get(ImplicitParam), ImplicitParamTy);
55 }
56
59 unsigned PrefixSize = Args.size() - 1;
60
61
62 if (RtlArgs) {
63
64
65
67 } else if (CE) {
68
69 unsigned ArgsToSkip = 0;
70 if (const auto *Op = dyn_cast(CE)) {
71 if (const auto *M = dyn_cast(Op->getCalleeDecl()))
72 ArgsToSkip =
73 static_cast<unsigned>(!M->isExplicitObjectMemberFunction());
74 }
77 } else {
78 assert(
80 "No CallExpr specified for function with non-zero number of arguments");
81 }
82 return {required, PrefixSize};
83}
84
89 llvm::CallBase **CallOrInvoke) {
93 *this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs);
94 auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall(
95 Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize);
99}
100
103 llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE,
104 llvm::CallBase **CallOrInvoke) {
106
107 assert(!ThisTy.isNull());
109 "Pointer/Object mixup");
110
113 if (SrcAS != DstAS) {
115 llvm::Type *NewType = CGM.getTypes().ConvertType(DstTy);
117 }
118
121 ImplicitParamTy, CE, Args, nullptr);
122 return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee,
126}
127
132
133
134
138
139
143 BaseQuals = PTy->getPointeeType().getQualifiers();
144 } else {
149 }
150
155 break;
156
161 break;
162
165 break;
166 }
167 } else {
168
169
170
171
172
174 }
175
177}
178
182 T = PTy->getPointeeType();
183 return T->castAsCXXRecordDecl();
184}
185
186
187
190 llvm::CallBase **CallOrInvoke) {
192
195
198
200
204 ReturnValue, nullptr, CallOrInvoke);
205 }
206
209 bool IsArrow = ME->isArrow();
211
213 HasQualifier, Qualifier, IsArrow,
214 Base, CallOrInvoke);
215}
216
220 const Expr *Base, llvm::CallBase **CallOrInvoke) {
222
223
224 bool CanUseVirtualCall = MD->isVirtual() && !HasQualifier;
225
226 const CXXMethodDecl *DevirtualizedMethod = nullptr;
227 if (CanUseVirtualCall &&
229 const CXXRecordDecl *BestDynamicDecl = Base->getBestDynamicClassType();
231 assert(DevirtualizedMethod);
233 const Expr *Inner = Base->IgnoreParenBaseCasts();
236
237
238
239
240
241 DevirtualizedMethod = nullptr;
242 else if (getCXXRecord(Inner) == DevirtualizedClass)
243
244
245 Base = Inner;
247
248
249
250
251 DevirtualizedMethod = nullptr;
252 }
253 }
254
255 bool TrivialForCodegen =
257 bool TrivialAssignment =
258 TrivialForCodegen &&
261
262
263
266 LValue TrivialAssignmentRHS;
267 if (auto *OCE = dyn_cast(CE)) {
268 if (OCE->isAssignmentOp()) {
269 if (TrivialAssignment) {
271 } else {
272 RtlArgs = &RtlArgStorage;
276 }
277 }
278 }
279
281 if (IsArrow) {
286 BaseInfo, TBAAInfo);
287 } else {
289 }
290
291 if (const CXXConstructorDecl *Ctor = dyn_cast(MD)) {
292
293
294 assert(!RtlArgs);
295 assert(ReturnValue.isNull() && "Constructor shouldn't have return value");
299 nullptr,
300 QualType(), CE, Args, nullptr);
301
303 false, This.getAddress(), Args,
305 false, CallOrInvoke);
307 }
308
309 if (TrivialForCodegen) {
312
313 if (TrivialAssignment) {
314
315
316
317
318
320 ? TrivialAssignmentRHS
324 }
325
327 "unknown trivial member function");
328 }
329
330
332 DevirtualizedMethod ? DevirtualizedMethod : MD;
334 if (const auto *Dtor = dyn_cast(CalleeDecl))
335 FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
337 else
338 FInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl);
339
340 llvm::FunctionType *Ty = CGM.getTypes().GetFunctionType(*FInfo);
341
342
343
344
347 if (CE)
349
351 if (const auto *CMCE = dyn_cast(CE)) {
352 auto *IOA = CMCE->getImplicitObjectArgument();
354 if (IsImplicitObjectCXXThis)
355 SkippedChecks.set(SanitizerKind::Alignment, true);
357 SkippedChecks.set(SanitizerKind::Null, true);
358 }
359
362 This.emitRawPointer(*this),
363 C.getCanonicalTagType(CalleeDecl->getParent()),
365
366
367
368
369
370
371
372 bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod;
373
374 if (const CXXDestructorDecl *Dtor = dyn_cast(CalleeDecl)) {
375 assert(CE->arguments().empty() &&
376 "Destructor shouldn't have explicit parameters");
377 assert(ReturnValue.isNull() && "Destructor shouldn't have return value");
378 if (UseVirtualCall) {
379 CGM.getCXXABI().EmitVirtualDestructorCall(
382 } else {
385 if (getLangOpts().AppleKext && Dtor->isVirtual() && HasQualifier)
387 else if (!DevirtualizedMethod)
388 Callee =
390 else {
392 }
393
395 IsArrow ? Base->getType()->getPointeeType() : Base->getType();
397 nullptr,
398 QualType(), CE, CallOrInvoke);
399 }
401 }
402
403
404
405
407 if (UseVirtualCall) {
409 } else {
410 if (SanOpts.has(SanitizerKind::CFINVCall) &&
412 llvm::Value *VTable;
414 std::tie(VTable, RD) = CGM.getCXXABI().LoadVTablePtr(
415 *this, This.getAddress(), CalleeDecl->getParent());
417 }
418
421 else if (!DevirtualizedMethod)
422 Callee =
424 else {
425 Callee =
428 }
429 }
430
433 CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
434 *this, CalleeDecl, This.getAddress(), UseVirtualCall);
435 This.setAddress(NewThisAddr);
436 }
437
440 nullptr, QualType(), CE, RtlArgs, CallOrInvoke);
441}
442
446 llvm::CallBase **CallOrInvoke) {
450 const Expr *MemFnExpr = BO->getRHS();
451
454 const auto *RD = MPT->getMostRecentCXXRecordDecl();
455
456
458 if (BO->getOpcode() == BO_PtrMemI)
460 else
462
463 CanQualType ClassType = CGM.getContext().getCanonicalTagType(RD);
465 ClassType);
466
467
469
470
471 llvm::Value *ThisPtrForCall = nullptr;
473 CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*this, BO, This,
474 ThisPtrForCall, MemFnPtr, MPT);
475
477
479
480
482
484
485
487 return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required,
488 0),
491}
492
497 "Trying to emit a member call expr on a static method!");
499 E, MD, ReturnValue, false, std::nullopt,
500 false, E->getArg(0), CallOrInvoke);
501}
502
505 llvm::CallBase **CallOrInvoke) {
506
508 return CGM.getCUDARuntime().EmitCUDADeviceKernelCallExpr(
510 return CGM.getCUDARuntime().EmitCUDAKernelCallExpr(*this, E, ReturnValue,
511 CallOrInvoke);
512}
513
517 if (Base->isEmpty())
518 return;
519
521
524
525
526
527
530
531
533 std::vector VBPtrOffsets =
535 for (CharUnits VBPtrOffset : VBPtrOffsets) {
536
537 if (VBPtrOffset >= NVSize)
538 break;
539 std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val();
540 CharUnits LastStoreOffset = LastStore.first;
541 CharUnits LastStoreSize = LastStore.second;
542
543 CharUnits SplitBeforeOffset = LastStoreOffset;
544 CharUnits SplitBeforeSize = VBPtrOffset - SplitBeforeOffset;
545 assert(!SplitBeforeSize.isNegative() && "negative store size!");
546 if (!SplitBeforeSize.isZero())
547 Stores.emplace_back(SplitBeforeOffset, SplitBeforeSize);
548
549 CharUnits SplitAfterOffset = VBPtrOffset + VBPtrWidth;
550 CharUnits SplitAfterSize = LastStoreSize - SplitAfterOffset;
551 assert(!SplitAfterSize.isNegative() && "negative store size!");
552 if (!SplitAfterSize.isZero())
553 Stores.emplace_back(SplitAfterOffset, SplitAfterSize);
554 }
555
556
557
558
559
560
561
563 if (!NullConstantForBase->isNullValue()) {
564 llvm::GlobalVariable *NullVariable = new llvm::GlobalVariable(
565 CGF.CGM.getModule(), NullConstantForBase->getType(),
566 true, llvm::GlobalVariable::PrivateLinkage,
567 NullConstantForBase, Twine());
568
571 NullVariable->setAlignment(Align.getAsAlign());
572
574
575
576 for (std::pair<CharUnits, CharUnits> Store : Stores) {
577 CharUnits StoreOffset = Store.first;
578 CharUnits StoreSize = Store.second;
579 llvm::Value *StoreSizeVal = CGF.CGM.getSize(StoreSize);
583 StoreSizeVal);
584 }
585
586
587
588
589 } else {
590 for (std::pair<CharUnits, CharUnits> Store : Stores) {
591 CharUnits StoreOffset = Store.first;
592 CharUnits StoreSize = Store.second;
593 llvm::Value *StoreSizeVal = CGF.CGM.getSize(StoreSize);
596 CGF.Builder.getInt8(0), StoreSizeVal);
597 }
598 }
599}
600
601void
604 assert(!Dest.isIgnored() && "Must have a destination!");
606
607
608
609
610
616 break;
621 break;
622 }
623 }
624
625
627 return;
628
629
631
632
633
634
635
638 assert(
641 return;
642 }
643
648 } else {
650 bool ForVirtualBase = false;
652
655
658 break;
659
662 break;
663
665 ForVirtualBase = true;
666 [[fallthrough]];
667
670 }
671
672
674 }
675}
676
678 const Expr *Exp) {
679 if (const ExprWithCleanups *E = dyn_cast(Exp))
680 Exp = E->getSubExpr();
682 "EmitSynthesizedCXXCopyCtor - unknown copy ctor expr");
686
687
688
689
690
693
695 && "EmitSynthesizedCXXCopyCtor - Copied-in Array");
697}
698
711
714 unsigned minElements,
715 llvm::Value *&numElements,
716 llvm::Value *&sizeWithoutCookie) {
718
721 sizeWithoutCookie
723 return sizeWithoutCookie;
724 }
725
726
727 unsigned sizeWidth = CGF.SizeTy->getBitWidth();
728
729
730 llvm::APInt cookieSize(sizeWidth,
732
733
734
735
738 if (!numElements)
741
742
743
744
745
746
747
748 bool isSigned
749 = (*e->getArraySize())->getType()->isSignedIntegerOrEnumerationType();
750 llvm::IntegerType *numElementsType
752 unsigned numElementsWidth = numElementsType->getBitWidth();
753
754
755 llvm::APInt arraySizeMultiplier(sizeWidth, 1);
758 type = CAT->getElementType();
759 arraySizeMultiplier *= CAT->getSize();
760 }
761
763 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.getQuantity());
764 typeSizeMultiplier *= arraySizeMultiplier;
765
766
767 llvm::Value *size;
768
769
770
771 if (llvm::ConstantInt *numElementsC =
772 dyn_castllvm::ConstantInt(numElements)) {
773 const llvm::APInt &count = numElementsC->getValue();
774
775 bool hasAnyOverflow = false;
776
777
778 if (isSigned && count.isNegative())
779 hasAnyOverflow = true;
780
781
782
783
784 else if (numElementsWidth > sizeWidth &&
785 numElementsWidth - sizeWidth > count.countl_zero())
786 hasAnyOverflow = true;
787
788
789 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
790
791
792
793 if (adjustedCount.ult(minElements))
794 hasAnyOverflow = true;
795
796
797
798
799 numElements = llvm::ConstantInt::get(CGF.SizeTy,
800 adjustedCount * arraySizeMultiplier);
801
802
803 bool overflow;
804 llvm::APInt allocationSize
805 = adjustedCount.umul_ov(typeSizeMultiplier, overflow);
806 hasAnyOverflow |= overflow;
807
808
809 if (cookieSize != 0) {
810
811
812 sizeWithoutCookie = llvm::ConstantInt::get(CGF.SizeTy, allocationSize);
813
814 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
815 hasAnyOverflow |= overflow;
816 }
817
818
819 if (hasAnyOverflow) {
820 size = llvm::Constant::getAllOnesValue(CGF.SizeTy);
821 } else {
822 size = llvm::ConstantInt::get(CGF.SizeTy, allocationSize);
823 }
824
825
826 } else {
827
828
829
830
831
832
833
834
835
836
837
838
839
840 llvm::Value *hasOverflow = nullptr;
841
842
843
844
845 if (numElementsWidth > sizeWidth) {
846 llvm::APInt threshold =
847 llvm::APInt::getOneBitSet(numElementsWidth, sizeWidth);
848
849 llvm::Value *thresholdV
850 = llvm::ConstantInt::get(numElementsType, threshold);
851
852 hasOverflow = CGF.Builder.CreateICmpUGE(numElements, thresholdV);
853 numElements = CGF.Builder.CreateTrunc(numElements, CGF.SizeTy);
854
855
856 } else if (isSigned) {
857 if (numElementsWidth < sizeWidth)
858 numElements = CGF.Builder.CreateSExt(numElements, CGF.SizeTy);
859
860
861
862
863
864
865 if (typeSizeMultiplier == 1)
866 hasOverflow = CGF.Builder.CreateICmpSLT(numElements,
867 llvm::ConstantInt::get(CGF.SizeTy, minElements));
868
869
870 } else if (numElementsWidth < sizeWidth) {
871 numElements = CGF.Builder.CreateZExt(numElements, CGF.SizeTy);
872 }
873
874 assert(numElements->getType() == CGF.SizeTy);
875
876 if (minElements) {
877
878 if (!hasOverflow) {
879 hasOverflow = CGF.Builder.CreateICmpULT(numElements,
880 llvm::ConstantInt::get(CGF.SizeTy, minElements));
881 } else if (numElementsWidth > sizeWidth) {
882
883
884
885 hasOverflow = CGF.Builder.CreateOr(hasOverflow,
886 CGF.Builder.CreateICmpULT(numElements,
887 llvm::ConstantInt::get(CGF.SizeTy, minElements)));
888 }
889 }
890
891 size = numElements;
892
893
894
895
896
897
898
899
900 if (typeSizeMultiplier != 1) {
901 llvm::Function *umul_with_overflow
903
904 llvm::Value *tsmV =
905 llvm::ConstantInt::get(CGF.SizeTy, typeSizeMultiplier);
906 llvm::Value *result =
907 CGF.Builder.CreateCall(umul_with_overflow, {size, tsmV});
908
909 llvm::Value *overflowed = CGF.Builder.CreateExtractValue(result, 1);
910 if (hasOverflow)
911 hasOverflow = CGF.Builder.CreateOr(hasOverflow, overflowed);
912 else
913 hasOverflow = overflowed;
914
915 size = CGF.Builder.CreateExtractValue(result, 0);
916
917
918 if (arraySizeMultiplier != 1) {
919
920
921 if (typeSize.isOne()) {
922 assert(arraySizeMultiplier == typeSizeMultiplier);
923 numElements = size;
924
925
926 } else {
927 llvm::Value *asmV =
928 llvm::ConstantInt::get(CGF.SizeTy, arraySizeMultiplier);
929 numElements = CGF.Builder.CreateMul(numElements, asmV);
930 }
931 }
932 } else {
933
934 assert(arraySizeMultiplier == 1);
935 }
936
937
938 if (cookieSize != 0) {
939 sizeWithoutCookie = size;
940
941 llvm::Function *uadd_with_overflow
943
944 llvm::Value *cookieSizeV = llvm::ConstantInt::get(CGF.SizeTy, cookieSize);
945 llvm::Value *result =
946 CGF.Builder.CreateCall(uadd_with_overflow, {size, cookieSizeV});
947
948 llvm::Value *overflowed = CGF.Builder.CreateExtractValue(result, 1);
949 if (hasOverflow)
950 hasOverflow = CGF.Builder.CreateOr(hasOverflow, overflowed);
951 else
952 hasOverflow = overflowed;
953
954 size = CGF.Builder.CreateExtractValue(result, 0);
955 }
956
957
958
959
960 if (hasOverflow)
961 size = CGF.Builder.CreateSelect(hasOverflow,
962 llvm::Constant::getAllOnesValue(CGF.SizeTy),
963 size);
964 }
965
966 if (cookieSize == 0)
967 sizeWithoutCookie = size;
968 else
969 assert(sizeWithoutCookie && "didn't set sizeWithoutCookie?");
970
971 return size;
972}
973
977
982 return;
985 true);
986 return;
996 return;
997 }
998 }
999 llvm_unreachable("bad evaluation kind");
1000}
1001
1004 Address BeginPtr, llvm::Value *NumElements,
1005 llvm::Value *AllocSizeWithoutCookie) {
1006
1007
1009 return;
1010
1011 Address CurPtr = BeginPtr;
1012
1013 unsigned InitListElements = 0;
1014
1019 bool pushedCleanup = false;
1020
1024
1025
1026 auto TryMemsetInitialization = [&]() -> bool {
1027
1028
1029 if (.getTypes().isZeroInitializable(ElementType))
1030 return false;
1031
1032
1033
1034
1035
1036 auto *RemainingSize = AllocSizeWithoutCookie;
1037 if (InitListElements) {
1038
1039 auto *InitializedSize = llvm::ConstantInt::get(
1040 RemainingSize->getType(),
1041 getContext().getTypeSizeInChars(ElementType).getQuantity() *
1042 InitListElements);
1043 RemainingSize = Builder.CreateSub(RemainingSize, InitializedSize);
1044 }
1045
1046
1047 Builder.CreateMemSet(CurPtr, Builder.getInt8(0), RemainingSize, false);
1048 return true;
1049 };
1050
1055 const Expr *IgnoreParen = nullptr;
1056 if (!ILE) {
1057 IgnoreParen = Init->IgnoreParenImpCasts();
1058 CPLIE = dyn_cast(IgnoreParen);
1059 SL = dyn_cast(IgnoreParen);
1060 OCEE = dyn_cast(IgnoreParen);
1061 }
1062
1063
1064 if (ILE || CPLIE || SL || OCEE) {
1065
1066
1068 if (!ILE)
1069 Init = IgnoreParen;
1070
1071
1072
1082
1083
1084 InitListElements =
1086 ->getZExtSize();
1087 CurPtr = Builder.CreateConstInBoundsGEP(
1088 CurPtr, InitListElements, "string.init.end");
1089
1090
1091 llvm::ConstantInt *ConstNum = dyn_castllvm::ConstantInt(NumElements);
1092 if (!ConstNum || !ConstNum->equalsInt(InitListElements)) {
1093 bool OK = TryMemsetInitialization();
1094 (void)OK;
1095 assert(OK && "couldn't memset character type?");
1096 }
1097 return;
1098 }
1099
1102 InitListElements = InitExprs.size();
1103
1104
1105
1107 if (const ConstantArrayType *CAT = dyn_cast_or_null(
1112 }
1113
1114
1115 if (DtorKind) {
1117
1118
1119
1120
1121 llvm::Instruction *DominatingIP =
1122 Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(Int8PtrTy));
1124 "array.init.end");
1126 EndOfInit, ElementType, ElementAlign,
1129 .AddAuxAllocas(AllocaTracker.Take());
1131 {EHStack.stable_begin(), DominatingIP});
1132 pushedCleanup = true;
1133 }
1134
1136 unsigned i = 0;
1137 for (const Expr *IE : InitExprs) {
1138
1139
1140
1141 if (EndOfInit.isValid()) {
1143 }
1144
1145
1146
1152 "array.exp.next"),
1155 }
1156
1157
1159
1160
1161
1162
1163 while (Init && Init->getType()->isConstantArrayType()) {
1164 auto *SubILE = dyn_cast(Init);
1165 if (!SubILE)
1166 break;
1167 assert(SubILE->getNumInits() == 0 && "explicit inits in array filler?");
1168 Init = SubILE->getArrayFiller();
1169 }
1170
1171
1173 }
1174
1175
1176
1177 llvm::ConstantInt *ConstNum = dyn_castllvm::ConstantInt(NumElements);
1178 if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
1179 return;
1180 }
1181
1182 assert(Init && "have trailing elements to initialize but no initializer");
1183
1184
1185
1189
1190
1191 if (!CCE->requiresZeroInitialization() || Ctor->getParent()->isEmpty())
1192 return;
1193
1194 if (TryMemsetInitialization())
1195 return;
1196 }
1197
1198
1199
1200
1201
1202 if (EndOfInit.isValid())
1204
1205
1206 if (InitListElements)
1207 NumElements = Builder.CreateSub(
1208 NumElements,
1209 llvm::ConstantInt::get(NumElements->getType(), InitListElements));
1211 true,
1212 CCE->requiresZeroInitialization());
1213 return;
1214 }
1215
1216
1219 if (TryMemsetInitialization())
1220 return;
1221
1222
1223
1224
1225 Init = &IVIE;
1226 }
1227
1228
1229
1230 assert(getContext().hasSameUnqualifiedType(ElementType, Init->getType()) &&
1231 "got wrong type of element to initialize");
1232
1233
1234 if (auto *ILE = dyn_cast(Init))
1235 if (ILE->getNumInits() == 0 && TryMemsetInitialization())
1236 return;
1237
1238
1239
1240 if (auto *ILE = dyn_cast(Init)) {
1241 if (const RecordType *RType =
1243 if (RType->getDecl()->isStruct()) {
1245 unsigned NumElements = 0;
1246 if (auto *CXXRD = dyn_cast(RD))
1247 NumElements = CXXRD->getNumBases();
1248 for (auto *Field : RD->fields())
1249 if (!Field->isUnnamedBitField())
1250 ++NumElements;
1251
1253 for (unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
1255 --NumElements;
1256 if (ILE->getNumInits() == NumElements && TryMemsetInitialization())
1257 return;
1258 }
1259 }
1260 }
1261
1262
1263 llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
1265 llvm::BasicBlock *ContBB = createBasicBlock("new.loop.end");
1266
1267
1268 llvm::Value *EndPtr = Builder.CreateInBoundsGEP(
1270 "array.end");
1271
1272
1273
1274 if (!ConstNum) {
1276 EndPtr, "array.isempty");
1277 Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
1278 }
1279
1280
1282
1283
1284 llvm::PHINode *CurPtrPhi =
1285 Builder.CreatePHI(CurPtr.getType(), 2, "array.cur");
1286 CurPtrPhi->addIncoming(CurPtr.emitRawPointer(*this), EntryBB);
1287
1289
1290
1291 if (EndOfInit.isValid())
1293
1294
1296 llvm::Instruction *DominatingIP =
1297 Builder.CreateFlagLoad(llvm::ConstantInt::getNullValue(Int8PtrTy));
1302 {EHStack.stable_begin(), DominatingIP});
1303 }
1304
1305
1308
1309
1311
1312
1313 llvm::Value *NextPtr = Builder.CreateConstInBoundsGEP1_32(
1314 ElementTy, CurPtr.emitRawPointer(*this), 1, "array.next");
1315
1316
1317
1318 llvm::Value *IsEnd = Builder.CreateICmpEQ(NextPtr, EndPtr, "array.atend");
1319 Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
1320 CurPtrPhi->addIncoming(NextPtr, Builder.GetInsertBlock());
1321
1323}
1324
1326 QualType ElementType, llvm::Type *ElementTy,
1327 Address NewPtr, llvm::Value *NumElements,
1328 llvm::Value *AllocSizeWithoutCookie) {
1332 AllocSizeWithoutCookie);
1336}
1337
1338
1339
1344 llvm::CallBase *CallOrInvoke;
1349 Args, CalleeType, false),
1351
1352
1353
1354
1355
1356
1357 llvm::Function *Fn = dyn_castllvm::Function(CalleePtr);
1359 Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
1360 CallOrInvoke->addFnAttr(llvm::Attribute::Builtin);
1361 }
1362
1363 return RV;
1364}
1365
1368 bool IsDelete) {
1371
1375
1377 if (auto *FD = dyn_cast(Decl))
1380 if (auto *CB = dyn_cast_if_presentllvm::CallBase(RV.getScalarVal())) {
1381 if (SanOpts.has(SanitizerKind::AllocToken)) {
1382
1384 }
1385 }
1386 return RV;
1387 }
1388 llvm_unreachable("predeclared global operator new/delete is missing");
1389}
1390
1391namespace {
1392
1393
1394
1395 template
1396 class CallDeleteDuringNew final : public EHScopeStack::Cleanup {
1397
1398 typedef typename Traits::ValueTy ValueTy;
1399
1400 typedef typename Traits::RValueTy RValueTy;
1401 struct PlacementArg {
1402 RValueTy ArgValue;
1404 };
1405
1406 unsigned NumPlacementArgs : 30;
1408 unsigned PassAlignmentToPlacementDelete : 1;
1410 RValueTy TypeIdentity;
1411 ValueTy Ptr;
1412 ValueTy AllocSize;
1414
1415 PlacementArg *getPlacementArgs() {
1416 return reinterpret_cast<PlacementArg *>(this + 1);
1417 }
1418
1419 public:
1420 static size_t getExtraSize(size_t NumPlacementArgs) {
1421 return NumPlacementArgs * sizeof(PlacementArg);
1422 }
1423
1424 CallDeleteDuringNew(size_t NumPlacementArgs,
1425 const FunctionDecl *OperatorDelete,
1426 RValueTy TypeIdentity, ValueTy Ptr, ValueTy AllocSize,
1427 const ImplicitAllocationParameters &IAP,
1428 CharUnits AllocAlign)
1429 : NumPlacementArgs(NumPlacementArgs),
1430 PassAlignmentToPlacementDelete(
1432 OperatorDelete(OperatorDelete), TypeIdentity(TypeIdentity), Ptr(Ptr),
1433 AllocSize(AllocSize), AllocAlign(AllocAlign) {}
1434
1435 void setPlacementArg(unsigned I, RValueTy Arg, QualType Type) {
1436 assert(I < NumPlacementArgs && "index out of range");
1437 getPlacementArgs()[I] = {Arg, Type};
1438 }
1439
1440 void Emit(CodeGenFunction &CGF, Flags flags) override {
1441 const auto *FPT = OperatorDelete->getType()->castAs();
1442 CallArgList DeleteArgs;
1443 unsigned FirstNonTypeArg = 0;
1445 TypeAwareAllocationMode::No;
1446 if (OperatorDelete->isTypeAwareOperatorNewOrDelete()) {
1447 TypeAwareDeallocation = TypeAwareAllocationMode::Yes;
1448 QualType SpecializedTypeIdentity = FPT->getParamType(0);
1449 ++FirstNonTypeArg;
1450 DeleteArgs.add(Traits::get(CGF, TypeIdentity), SpecializedTypeIdentity);
1451 }
1452
1453
1454 DeleteArgs.add(Traits::get(CGF, Ptr), FPT->getParamType(FirstNonTypeArg));
1455
1456
1457 UsualDeleteParams Params;
1458 if (NumPlacementArgs) {
1459
1460
1465 } else {
1466
1467
1468 Params = OperatorDelete->getUsualDeleteParams();
1469 }
1470
1472 "should not call destroying delete in a new-expression");
1473
1474
1475 if (Params.Size)
1476 DeleteArgs.add(Traits::get(CGF, AllocSize),
1478
1479
1480
1481
1482
1484 DeleteArgs.add(RValue::get(llvm::ConstantInt::get(
1487
1488
1489 for (unsigned I = 0; I != NumPlacementArgs; ++I) {
1490 auto Arg = getPlacementArgs()[I];
1491 DeleteArgs.add(Traits::get(CGF, Arg.ArgValue), Arg.ArgType);
1492 }
1493
1494
1496 }
1497 };
1498}
1499
1500
1501
1504 llvm::Value *AllocSize, CharUnits AllocAlign,
1507
1508
1509
1511 struct DirectCleanupTraits {
1512 typedef llvm::Value *ValueTy;
1513 typedef RValue RValueTy;
1516 };
1517
1518 typedef CallDeleteDuringNew DirectCleanup;
1519
1522 TypeIdentity, NewPtr.emitRawPointer(CGF), AllocSize,
1525 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1526 Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty);
1527 }
1528
1529 return;
1530 }
1531
1532
1539 struct ConditionalCleanupTraits {
1543 return V.restore(CGF);
1544 }
1545 };
1546 typedef CallDeleteDuringNew ConditionalCleanup;
1547
1548 ConditionalCleanup *Cleanup =
1551 SavedTypeIdentity, SavedNewPtr, SavedAllocSize,
1554 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1555 Cleanup->setPlacementArg(
1557 }
1558
1560}
1561
1563
1565
1566
1568
1569
1570
1571 unsigned minElements = 0;
1572 unsigned IndexOfAlignArg = 1;
1577 const Expr *IgnoreParen = Init->IgnoreParenImpCasts();
1580 minElements =
1582 ->getZExtSize();
1583 } else if (ILE || CPLIE) {
1585 }
1586 }
1587
1588 llvm::Value *numElements = nullptr;
1589 llvm::Value *allocSizeWithoutCookie = nullptr;
1590 llvm::Value *allocSize =
1592 allocSizeWithoutCookie);
1594
1595
1596
1599 RValue TypeIdentityArg;
1600 if (allocator->isReservedGlobalPlacementOperator()) {
1603
1606
1607
1608
1609
1612
1613
1614
1618 allocatorArgs.add(RValue::get(allocation, *this), arg->getType());
1619 }
1620
1621 } else {
1625 unsigned ParamsToSkip = 0;
1631 allocatorArgs.add(TypeIdentityArg, SpecializedTypeIdentity);
1632 ++ParamsToSkip;
1633 ++IndexOfAlignArg;
1634 }
1635
1637 allocatorArgs.add(RValue::get(allocSize), sizeType);
1638 ++ParamsToSkip;
1639
1640 if (allocSize != allocSizeWithoutCookie) {
1642 allocAlign = std::max(allocAlign, cookieAlign);
1643 }
1644
1645
1647 QualType AlignValT = sizeType;
1648 if (allocatorType->getNumParams() > IndexOfAlignArg) {
1649 AlignValT = allocatorType->getParamType(IndexOfAlignArg);
1650 assert(getContext().hasSameUnqualifiedType(
1652 "wrong type for alignment parameter");
1653 ++ParamsToSkip;
1654 } else {
1655
1656 assert(allocator->isVariadic() && "can't pass alignment to allocator");
1657 }
1658 allocatorArgs.add(
1660 AlignValT);
1661 }
1662
1663
1665 AbstractCallee(), ParamsToSkip);
1666
1668 EmitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs);
1669
1670 if (auto *newCall = dyn_castllvm::CallBase(RV.getScalarVal())) {
1672
1673 CGDI->addHeapAllocSiteMetadata(newCall, allocType, E->getExprLoc());
1674 }
1675 if (SanOpts.has(SanitizerKind::AllocToken)) {
1676
1678 }
1679 }
1680
1681
1682
1683
1684
1685 CharUnits allocationAlign = allocAlign;
1687 allocator->isReplaceableGlobalAllocationFunction()) {
1688 unsigned AllocatorAlign = llvm::bit_floor(std::min<uint64_t>(
1690 allocationAlign = std::max(
1691 allocationAlign, getContext().toCharUnitsFromBits(AllocatorAlign));
1692 }
1693
1695 }
1696
1697
1698
1699
1700
1704
1705 llvm::BasicBlock *nullCheckBB = nullptr;
1706 llvm::BasicBlock *contBB = nullptr;
1707
1708
1709
1711
1712 if (nullCheck) {
1713 conditional.begin(*this);
1714
1715 nullCheckBB = Builder.GetInsertBlock();
1716 llvm::BasicBlock *notNullBB = createBasicBlock("new.notnull");
1718
1719 llvm::Value *isNull = Builder.CreateIsNull(allocation, "new.isnull");
1720 Builder.CreateCondBr(isNull, contBB, notNullBB);
1722 }
1723
1724
1725
1727 llvm::Instruction *cleanupDominator = nullptr;
1731 allocAlign, allocatorArgs);
1732 operatorDeleteCleanup = EHStack.stable_begin();
1733 cleanupDominator = Builder.CreateUnreachable();
1734 }
1735
1736 assert((allocSize == allocSizeWithoutCookie) ==
1738 if (allocSize != allocSizeWithoutCookie) {
1740 allocation = CGM.getCXXABI().InitializeArrayCookie(*this, allocation,
1741 numElements,
1742 E, allocType);
1743 }
1744
1747
1748
1749
1750
1751
1752 if (CGM.getCodeGenOpts().StrictVTablePointers &&
1753 allocator->isReservedGlobalPlacementOperator())
1754 result = Builder.CreateLaunderInvariantGroup(result);
1755
1756
1757
1758
1759
1760
1762 SkippedChecks.set(SanitizerKind::Null, nullCheck);
1765 result, allocType, result.getAlignment(), SkippedChecks,
1766 numElements);
1767
1768 EmitNewInitializer(*this, E, allocType, elementTy, result, numElements,
1769 allocSizeWithoutCookie);
1770 llvm::Value *resultPtr = result.emitRawPointer(*this);
1771
1772
1773
1774 if (operatorDeleteCleanup.isValid()) {
1776 cleanupDominator->eraseFromParent();
1777 }
1778
1779 if (nullCheck) {
1780 conditional.end(*this);
1781
1782 llvm::BasicBlock *notNullBB = Builder.GetInsertBlock();
1784
1785 llvm::PHINode *PHI = Builder.CreatePHI(resultPtr->getType(), 2);
1786 PHI->addIncoming(resultPtr, notNullBB);
1787 PHI->addIncoming(llvm::Constant::getNullValue(resultPtr->getType()),
1788 nullCheckBB);
1789
1790 resultPtr = PHI;
1791 }
1792
1793 return resultPtr;
1794}
1795
1797 llvm::Value *DeletePtr, QualType DeleteTy,
1798 llvm::Value *NumElements,
1800 assert((!NumElements && CookieSize.isZero()) ||
1802
1805
1807 auto ParamTypeIt = DeleteFTy->param_type_begin();
1808
1809 std::optional<llvm::AllocaInst *> TagAlloca;
1810 auto EmitTag = [&](QualType TagType, const char *TagName) {
1811 assert(!TagAlloca);
1813 CharUnits Align = CGM.getNaturalTypeAlignment(TagType);
1814 llvm::AllocaInst *TagAllocation = CreateTempAlloca(Ty, TagName);
1815 TagAllocation->setAlignment(Align.getAsAlign());
1817 TagType);
1818 TagAlloca = TagAllocation;
1819 };
1820
1821
1823 EmitTag(*ParamTypeIt++, "typeaware.delete.tag");
1824
1825
1826 QualType ArgTy = *ParamTypeIt++;
1827 DeleteArgs.add(RValue::get(DeletePtr), ArgTy);
1828
1829
1831 EmitTag(*ParamTypeIt++, "destroying.delete.tag");
1832
1833
1834 if (Params.Size) {
1835 QualType SizeType = *ParamTypeIt++;
1837 llvm::Value *Size = llvm::ConstantInt::get(ConvertType(SizeType),
1839
1840
1841 if (NumElements)
1842 Size = Builder.CreateMul(Size, NumElements);
1843
1844
1845 if (!CookieSize.isZero())
1846 Size = Builder.CreateAdd(
1847 Size, llvm::ConstantInt::get(SizeTy, CookieSize.getQuantity()));
1848
1849 DeleteArgs.add(RValue::get(Size), SizeType);
1850 }
1851
1852
1854 QualType AlignValType = *ParamTypeIt++;
1857 DeleteTy, true ));
1858 llvm::Value *Align = llvm::ConstantInt::get(ConvertType(AlignValType),
1860 DeleteArgs.add(RValue::get(Align), AlignValType);
1861 }
1862
1863 assert(ParamTypeIt == DeleteFTy->param_type_end() &&
1864 "unknown parameter to usual delete function");
1865
1866
1868
1869
1870
1871 if (TagAlloca && (*TagAlloca)->use_empty())
1872 (*TagAlloca)->eraseFromParent();
1873}
1874namespace {
1875
1876 struct CallObjectDelete final : EHScopeStack::Cleanup {
1877 llvm::Value *Ptr;
1880
1881 CallObjectDelete(llvm::Value *Ptr,
1884 : Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
1885
1887 CGF.EmitDeleteCall(OperatorDelete, Ptr, ElementType);
1888 }
1889 };
1890}
1891
1892void
1894 llvm::Value *CompletePtr,
1897 OperatorDelete, ElementType);
1898}
1899
1900
1901
1902
1903
1908 if (Dtor && Dtor->isVirtual())
1910 Dtor);
1911 else
1913 ElementType);
1914}
1915
1916
1917
1918
1921 llvm::BasicBlock *UnconditionalDeleteBlock) {
1922
1923
1924
1925
1926
1928 ElementType);
1929
1931 assert(!OperatorDelete->isDestroyingOperatorDelete());
1932
1933
1934
1937 if (RD->hasDefinition() && !RD->hasTrivialDestructor()) {
1938 Dtor = RD->getDestructor();
1939
1941 bool UseVirtualCall = true;
1943 if (auto *DevirtualizedDtor =
1944 dyn_cast_or_null(
1947 UseVirtualCall = false;
1951
1952
1953 Dtor = DevirtualizedDtor;
1954 } else {
1955
1956
1957
1958
1959
1960 UseVirtualCall = true;
1961 }
1962 }
1963 if (UseVirtualCall) {
1965 Dtor);
1966 return false;
1967 }
1968 }
1969 }
1970 }
1971
1972
1973
1974
1975 CGF.EHStack.pushCleanup(
1977
1978 if (Dtor)
1980 false,
1981 false,
1982 Ptr, ElementType);
1983 else if (auto Lifetime = ElementType.getObjCLifetime()) {
1984 switch (Lifetime) {
1988 break;
1989
1992 break;
1993
1996 break;
1997 }
1998 }
1999
2000
2002 CGF.EmitBlock(UnconditionalDeleteBlock);
2004 return true;
2005 }
2006
2008 return false;
2009}
2010
2011namespace {
2012
2013 struct CallArrayDelete final : EHScopeStack::Cleanup {
2014 llvm::Value *Ptr;
2015 const FunctionDecl *OperatorDelete;
2016 llvm::Value *NumElements;
2017 QualType ElementType;
2018 CharUnits CookieSize;
2019
2020 CallArrayDelete(llvm::Value *Ptr,
2021 const FunctionDecl *OperatorDelete,
2022 llvm::Value *NumElements,
2023 QualType ElementType,
2024 CharUnits CookieSize)
2025 : Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
2026 ElementType(ElementType), CookieSize(CookieSize) {}
2027
2028 void Emit(CodeGenFunction &CGF, Flags flags) override {
2029 CGF.EmitDeleteCall(OperatorDelete, Ptr, ElementType, NumElements,
2030 CookieSize);
2031 }
2032 };
2033}
2034
2035
2040 llvm::Value *numElements = nullptr;
2041 llvm::Value *allocatedPtr = nullptr;
2044 numElements, allocatedPtr, cookieSize);
2045
2046 assert(allocatedPtr && "ReadArrayCookie didn't set allocated pointer");
2047
2048
2051 allocatedPtr, operatorDelete,
2052 numElements, elementType,
2053 cookieSize);
2054
2055
2057 assert(numElements && "no element count for a type with a destructor!");
2058
2062
2063 llvm::Value *arrayBegin = deletedPtr.emitRawPointer(CGF);
2065 deletedPtr.getElementType(), arrayBegin, numElements, "delete.end");
2066
2067
2068
2069
2070 CGF.emitArrayDestroy(arrayBegin, arrayEnd, elementType, elementAlign,
2072 true,
2074 }
2075
2076
2078}
2079
2083
2084
2085
2086
2087
2088
2089
2090
2091 llvm::BasicBlock *DeleteNotNull = createBasicBlock("delete.notnull");
2092 llvm::BasicBlock *DeleteEnd = createBasicBlock("delete.end");
2093
2094 llvm::Value *IsNull = Builder.CreateIsNull(Ptr, "isnull");
2095
2096 Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
2099
2101
2102
2103
2107 return;
2108 }
2109
2110
2113
2115 CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2116 CGM.getContext().getLangOpts())) {
2118 auto *Dtor = RD->getDestructor();
2119 if (Dtor && Dtor->isVirtual()) {
2120 llvm::Value *NumElements = nullptr;
2121 llvm::Value *AllocatedPtr = nullptr;
2124 llvm::BasicBlock *DoneBB = createBasicBlock("vdtor.nocall");
2125
2126
2127 CGM.getCXXABI().ReadArrayCookie(*this, Ptr, E, DeleteTy, NumElements,
2128 AllocatedPtr, CookieSize);
2129
2131 llvm::Value *IsEmpty = Builder.CreateICmpEQ(
2132 NumElements, llvm::ConstantInt::get(CondTy, 0));
2133 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
2134
2135
2138 EmitDeleteCall(OperatorDelete, AllocatedPtr, DeleteTy, NumElements,
2139 CookieSize);
2141
2145 return;
2146 }
2147 }
2148 }
2149
2153 } else {
2156 }
2157}
2158
2160 llvm::Type *StdTypeInfoPtrTy,
2161 bool HasNullCheck) {
2162
2164
2166
2167
2168
2169
2170
2172 ThisPtr, SrcRecordTy);
2173
2174
2175
2176
2177 if (HasNullCheck &&
2179 llvm::BasicBlock *BadTypeidBlock =
2181 llvm::BasicBlock *EndBlock = CGF.createBasicBlock("typeid.end");
2182
2184 CGF.Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock);
2185
2189 }
2190
2192 StdTypeInfoPtrTy);
2193}
2194
2196
2197
2198
2199
2200
2202 LangAS GlobAS = CGM.GetGlobalVarAddressSpace(nullptr);
2203
2204 auto MaybeASCast = [=](auto &&TypeInfo) {
2208 };
2209
2213 return MaybeASCast(TypeInfo);
2214 }
2215
2216
2217
2218
2219
2220
2221
2225
2227 return MaybeASCast(CGM.GetAddrOfRTTIDescriptor(OperandTy));
2228}
2229
2232 llvm::Type *DestLTy = CGF.ConvertType(DestTy);
2234 return llvm::Constant::getNullValue(DestLTy);
2235
2236
2237
2239 return nullptr;
2240
2241 CGF.Builder.ClearInsertionPoint();
2242 return llvm::PoisonValue::get(DestLTy);
2243}
2244
2247 CGM.EmitExplicitCastExprType(DCE, this);
2249
2251
2252
2253
2254
2258 if (IsDynamicCastToVoid) {
2260
2264 } else {
2265 SrcRecordTy = SrcTy;
2267 }
2268
2269
2270
2271
2272
2273
2275
2278
2279 if (.GetInsertBlock())
2281 return T;
2282 }
2283 }
2284
2285 assert(SrcRecordTy->isRecordType() && "source type must be a record type!");
2286
2287
2288
2289 bool IsExact = !IsDynamicCastToVoid &&
2290 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2292 CGM.getCXXABI().shouldEmitExactDynamicCast(DestRecordTy);
2293
2294 std::optionalCGCXXABI::ExactDynamicCastInfo ExactCastInfo;
2295 if (IsExact) {
2296 ExactCastInfo = CGM.getCXXABI().getExactDynamicCastInfo(SrcRecordTy, DestTy,
2297 DestRecordTy);
2298 if (!ExactCastInfo) {
2300 if (.GetInsertBlock())
2302 return NullValue;
2303 }
2304 }
2305
2306
2307
2308
2309 bool ShouldNullCheckSrcValue =
2310 IsExact || CGM.getCXXABI().shouldDynamicCastCallBeNullChecked(
2312
2313 llvm::BasicBlock *CastNull = nullptr;
2314 llvm::BasicBlock *CastNotNull = nullptr;
2315 llvm::BasicBlock *CastEnd = createBasicBlock("dynamic_cast.end");
2316
2317 if (ShouldNullCheckSrcValue) {
2320
2321 llvm::Value *IsNull = Builder.CreateIsNull(ThisAddr);
2322 Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
2324 }
2325
2326 llvm::Value *Value;
2327 if (IsDynamicCastToVoid) {
2328 Value = CGM.getCXXABI().emitDynamicCastToVoid(*this, ThisAddr, SrcRecordTy);
2329 } else if (IsExact) {
2330
2331
2332 Value = CGM.getCXXABI().emitExactDynamicCast(
2333 *this, ThisAddr, SrcRecordTy, DestTy, DestRecordTy, *ExactCastInfo,
2334 CastEnd, CastNull);
2335 } else {
2337 "destination type must be a record type!");
2338 Value = CGM.getCXXABI().emitDynamicCastCall(*this, ThisAddr, SrcRecordTy,
2339 DestTy, DestRecordTy, CastEnd);
2340 }
2341 CastNotNull = Builder.GetInsertBlock();
2342
2343 llvm::Value *NullValue = nullptr;
2344 if (ShouldNullCheckSrcValue) {
2346
2349 CastNull = Builder.GetInsertBlock();
2350
2352 }
2353
2355
2356 if (CastNull) {
2358 PHI->addIncoming(Value, CastNotNull);
2359 PHI->addIncoming(NullValue, CastNull);
2360
2362 }
2363
2365}
static MemberCallInfo commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE, CallArgList &Args, CallArgList *RtlArgs)
Definition CGExprCXX.cpp:36
static llvm::Value * EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, llvm::Type *StdTypeInfoPtrTy, bool HasNullCheck)
Definition CGExprCXX.cpp:2159
static llvm::Value * EmitDynamicCastToNull(CodeGenFunction &CGF, QualType DestTy)
Definition CGExprCXX.cpp:2230
static RValue EmitNewDeleteCall(CodeGenFunction &CGF, const FunctionDecl *CalleeDecl, const FunctionProtoType *CalleeType, const CallArgList &Args)
Emit a call to an operator new or operator delete function, as implicitly created by new-expressions ...
Definition CGExprCXX.cpp:1340
static void EmitDestroyingObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType)
Emit the code for deleting a single object with a destroying operator delete.
Definition CGExprCXX.cpp:1904
static void EmitNullBaseClassInitialization(CodeGenFunction &CGF, Address DestPtr, const CXXRecordDecl *Base)
Definition CGExprCXX.cpp:514
static bool EmitObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, llvm::BasicBlock *UnconditionalDeleteBlock)
Emit the code for deleting a single object.
Definition CGExprCXX.cpp:1919
static CXXRecordDecl * getCXXRecord(const Expr *E)
Definition CGExprCXX.cpp:179
static void EnterNewDeleteCleanup(CodeGenFunction &CGF, const CXXNewExpr *E, RValue TypeIdentity, Address NewPtr, llvm::Value *AllocSize, CharUnits AllocAlign, const CallArgList &NewArgs)
Enter a cleanup to call 'operator delete' if the initializer in a new-expression throws.
Definition CGExprCXX.cpp:1502
static CharUnits CalculateCookiePadding(CodeGenFunction &CGF, const CXXNewExpr *E)
Definition CGExprCXX.cpp:699
static void EmitArrayDelete(CodeGenFunction &CGF, const CXXDeleteExpr *E, Address deletedPtr, QualType elementType)
Emit the code for deleting an array of objects.
Definition CGExprCXX.cpp:2036
static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, QualType AllocType, Address NewPtr, AggValueSlot::Overlap_t MayOverlap)
Definition CGExprCXX.cpp:974
static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E, QualType ElementType, llvm::Type *ElementTy, Address NewPtr, llvm::Value *NumElements, llvm::Value *AllocSizeWithoutCookie)
Definition CGExprCXX.cpp:1325
static llvm::Value * EmitCXXNewAllocSize(CodeGenFunction &CGF, const CXXNewExpr *e, unsigned minElements, llvm::Value *&numElements, llvm::Value *&sizeWithoutCookie)
Definition CGExprCXX.cpp:712
static QualType getPointeeType(const MemRegion *R)
a trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
DeclarationNameTable DeclarationNames
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a call to a CUDA kernel function.
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
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.
CXXConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ destructor within a class.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
bool isAlwaysNull() const
isAlwaysNull - Return whether the result of the dynamic_cast is proven to always be null.
Represents a call to a member function that may be written either with member call syntax (e....
SourceLocation getExprLoc() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Qualifiers getMethodQualifiers() const
CXXMethodDecl * getDevirtualizedMethod(const Expr *Base, bool IsAppleKext)
If it's possible to devirtualize a call to this method, return the called function.
CXXMethodDecl * getCorrespondingMethodInClass(const CXXRecordDecl *RD, bool MayBeBase=false)
Find the method in RD that corresponds to this one.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
llvm::iterator_range< arg_iterator > placement_arguments()
QualType getAllocatedType() const
unsigned getNumImplicitArgs() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
ImplicitAllocationParameters implicitAllocationParameters() const
Provides the full set of information about expected implicit parameters in this call.
bool hasInitializer() const
Whether this new-expression has any initializer at all.
bool shouldNullCheckAllocation() const
True if the allocation result needs to be null-checked.
bool passAlignment() const
Indicates whether the required alignment should be implicitly passed to the allocation function.
FunctionDecl * getOperatorDelete() const
unsigned getNumPlacementArgs() const
TypeSourceInfo * getAllocatedTypeSourceInfo() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
A call to an overloaded operator written using operator syntax.
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool isDynamicClass() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
An expression "T()" which creates an rvalue of a non-class type T.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isMostDerived(const ASTContext &Context) const
Best-effort check if the expression operand refers to a most derived object.
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
bool hasNullCheck() const
Whether this is of a form like "typeid(*ptr)" that can throw a std::bad_typeid if a pointer is a null...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
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...
CharUnits getAlignment() const
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.
Address setKnownNonNull()
void setAlignment(CharUnits Value)
llvm::PointerType * getType() const
Return the type of the pointer value.
bool isSanitizerChecked() const
Address getAddress() const
IsZeroed_t isZeroed() const
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.
A scoped helper to set the current debug location to the specified location or preferred location of ...
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual std::vector< CharUnits > getVBPtrOffsets(const CXXRecordDecl *RD)
Gets the offsets of all the virtual base pointers in a given class.
virtual void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr, const CXXDeleteExpr *expr, QualType ElementType, llvm::Value *&NumElements, llvm::Value *&AllocPtr, CharUnits &CookieSize)
Reads the array cookie associated with the given pointer, if it has one.
virtual bool shouldTypeidBeNullChecked(QualType SrcRecordTy)=0
virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0
virtual const CXXRecordDecl * getThisArgumentTypeForMethod(GlobalDecl GD)
Get the type of the implicit "this" parameter used by a method.
virtual bool EmitBadCastCall(CodeGenFunction &CGF)=0
virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0
virtual CharUnits GetArrayCookieSize(const CXXNewExpr *expr)
Returns the extra size required in order to store the array cookie for the given new-expression.
virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0
All available information about a concrete callee.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
An abstract representation of regular/ObjC call/message targets.
An object to manage conditionally-evaluated expressions.
void begin(CodeGenFunction &CGF)
void end(CodeGenFunction &CGF)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, QualType elementType, CharUnits elementAlign, Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup)
emitArrayDestroy - Destroys all the elements of the given array, beginning from last to first.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest)
Definition CGExprCXX.cpp:602
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 EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
llvm::Type * ConvertType(QualType T)
RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E)
Definition CGExprCXX.cpp:128
RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, bool HasQualifier, NestedNameSpecifier Qualifier, bool IsArrow, const Expr *Base, llvm::CallBase **CallOrInvoke)
Definition CGExprCXX.cpp:217
void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
void EmitARCDestroyWeak(Address addr)
void @objc_destroyWeak(i8** addr) Essentially objc_storeWeak(addr, nil).
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
pushRegularPartialArrayCleanup - Push an EH cleanup to destroy already-constructed elements of the gi...
void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp)
Definition CGExprCXX.cpp:677
llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
Definition CGExprCXX.cpp:2080
const LangOptions & getLangOpts() const
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, bool NewPointerIsChecked, bool ZeroInitialization=false)
EmitCXXAggrConstructorCall - Emit a loop to call a particular constructor for each of several members...
@ TCK_ConstructorCall
Checking the 'this' pointer for a constructor call.
@ TCK_MemberCall
Checking the 'this' pointer for a call to a non-static member function.
@ TCK_DynamicOperation
Checking the operand of a dynamic_cast or a typeid expression.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
Definition CGExprCXX.cpp:1562
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, Address arrayEndPointer, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
pushIrregularPartialArrayCleanup - Push a NormalAndEHCleanup to destroy already-constructed elements ...
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy)
Emit an aggregate assignment.
void EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
Release the given object.
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
Definition CGExprCXX.cpp:1893
RValue EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method, const CGCallee &Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E, CallArgList *RtlArgs, llvm::CallBase **CallOrInvoke)
Definition CGExprCXX.cpp:85
@ ForceRightToLeft
! Language semantics require right-to-left evaluation.
RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
Definition CGExprCXX.cpp:503
void initFullExprCleanup()
Set up the last cleanup that was pushed as a conditional full-expression cleanup.
bool isInConditionalBranch() const
isInConditionalBranch - Return true if we're currently emitting one branch or the other of a conditio...
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
Destroy a __strong variable.
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, AggValueSlot ThisAVS, const CXXConstructExpr *E)
CGDebugInfo * getDebugInfo()
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke=nullptr)
Definition CGExprCXX.cpp:188
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
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,...
const TargetCodeGenInfo & getTargetHooks() const
RValue EmitAnyExprToTemp(const Expr *E)
EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will always be accessible even if...
ASTContext & getContext() const
void EmitAllocToken(llvm::CallBase *CB, QualType AllocType)
Emit and set additional metadata used by the AllocToken instrumentation.
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, const CallExpr *TheCallExpr, bool IsDelete)
Definition CGExprCXX.cpp:1366
llvm::Type * ConvertTypeForMem(QualType T)
void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, Address This, Address Src, const CXXConstructExpr *E)
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
Definition CGExprCXX.cpp:1796
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
const TargetInfo & Target
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD, NestedNameSpecifier Qual, llvm::Type *Ty)
BuildAppleKextVirtualCall - This routine is to support gcc's kext ABI making indirect call to virtual...
RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
Definition CGExprCXX.cpp:444
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
static bool IsWrappedCXXThis(const Expr *E)
Check if E is a C++ "this" pointer wrapped in value-preserving casts.
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)
const CallExpr * MustTailCall
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType, llvm::Type *ElementTy, Address NewPtr, llvm::Value *NumElements, llvm::Value *AllocSizeWithoutCookie)
Definition CGExprCXX.cpp:1002
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
Definition CGExprCXX.cpp:493
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
Definition CGExprCXX.cpp:2245
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Value * EmitCXXTypeidExpr(const CXXTypeidExpr *E)
Definition CGExprCXX.cpp:2195
llvm::Module & getModule() const
llvm::Constant * EmitNullConstantForBase(const CXXRecordDecl *Record)
Return a null constant appropriate for zero-initializing a base class with the given type.
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
CGCXXABI & getCXXABI() const
const CodeGenOptions & getCodeGenOpts() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
CanQualType DeriveThisType(const CXXRecordDecl *RD, const CXXMethodDecl *MD)
Derives the 'this' type for codegen purposes, i.e.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)
Figure out the rules for calling a function with the given formal type using the given arguments.
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
A saved depth on the scope stack.
T * pushCleanupWithExtra(CleanupKind Kind, size_t N, As... A)
Push a cleanup with non-constant storage requirements on the stack.
LValue - This represents an lvalue references.
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
A class for recording the number of arguments that a function signature requires.
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Represents the canonical version of C arrays with a specified constant size.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
The name of a declaration.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
QualType getReturnType() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isReplaceableGlobalAllocationFunction(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
UsualDeleteParams getUsualDeleteParams() const
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
bool isDefaulted() const
Whether this function is defaulted.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits()
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
bool hasQualifier() const
Determines whether this member expression actually had a C++ nested-name-specifier prior to the name ...
A pointer to member type per C++ 8.3.3 - Pointers to members.
QualType getPointeeType() const
Represents a C++ nested name specifier, such as "\::std::vector::".
ObjCEncodeExpr, used for @encode in Objective-C.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getCanonicalType() const
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
bool hasStrongOrWeakObjCLifetime() const
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.
LangAS getAddressSpace() const
Represents a struct/union/class.
field_range fields() const
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
RecordDecl * getDefinitionOrSelf() const
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const
Get the begin source location.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isVoidPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
EnumDecl * castAsEnumDecl() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * getAs() const
Member-template getAs'.
bool isRecordType() const
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
AlignedAllocationMode alignedAllocationModeFromBool(bool IsAligned)
bool isAlignedAllocation(AlignedAllocationMode Mode)
const FunctionProtoType * T
@ Dtor_Complete
Complete object dtor.
@ Type
The name was classified as a type.
bool isTypeAwareAllocation(TypeAwareAllocationMode Mode)
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getPointerSize() const
llvm::IntegerType * SizeTy
CharUnits getSizeAlign() const
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function.
static saved_type save(CodeGenFunction &CGF, type value)
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
TypeAwareAllocationMode TypeAwareDelete
AlignedAllocationMode Alignment