22#include "llvm/IR/Intrinsics.h"
28struct MemberCallInfo {
37 llvm::Value *
This, llvm::Value *ImplicitParam,
44 assert(MD->isImplicitObjectMemberFunction() &&
45 "Trying to emit a member or operator call expr on a static method!");
59 unsigned PrefixSize = Args.size() - 1;
69 unsigned ArgsToSkip = 0;
70 if (
const auto *Op = dyn_cast<CXXOperatorCallExpr>(CE)) {
71 if (
const auto *M = dyn_cast<CXXMethodDecl>(Op->getCalleeDecl()))
73 static_cast<unsigned>(!M->isExplicitObjectMemberFunction());
80 "No CallExpr specified for function with non-zero number of arguments");
82 return {required, PrefixSize};
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,
105 llvm::CallBase **CallOrInvoke) {
110 "Pointer/Object mixup");
114 if (SrcAS != DstAS) {
116 llvm::Type *NewType =
CGM.getTypes().ConvertType(DstTy);
122 ImplicitParamTy, CE, Args,
nullptr);
123 return EmitCall(
CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee,
144 BaseQuals = PTy->getPointeeType().getQualifiers();
183 T = PTy->getPointeeType();
184 return T->castAsCXXRecordDecl();
191 llvm::CallBase **CallOrInvoke) {
214 HasQualifier, Qualifier, IsArrow,
221 const Expr *
Base, llvm::CallBase **CallOrInvoke) {
225 bool CanUseVirtualCall = MD->
isVirtual() && !HasQualifier;
228 if (CanUseVirtualCall &&
232 assert(DevirtualizedMethod);
234 const Expr *Inner =
Base->IgnoreParenBaseCasts();
242 DevirtualizedMethod =
nullptr;
252 DevirtualizedMethod =
nullptr;
262 LValue TrivialAssignmentRHS;
263 if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
264 if (OCE->isAssignmentOp()) {
265 if (TrivialAssignment) {
268 RtlArgs = &RtlArgStorage;
271 0, EvaluationOrder::ForceRightToLeft);
276 std::optional<LValue> HLSLThisLValue;
277 if (
auto *HLSLOutArg = dyn_cast<HLSLOutArgExpr>(
Base)) {
279 RtlArgs = &RtlArgStorage;
281 HLSLOutArg, *RtlArgs, HLSLOutArg->getType(),
true);
286 auto getLValueForThis = [
this, IsArrow,
Base,
287 HLSLThisLValue](
bool EmitCheckedForStore =
false) {
297 return *HLSLThisLValue;
298 if (EmitCheckedForStore)
307 assert(
ReturnValue.isNull() &&
"Constructor shouldn't have return value");
316 false,
This.getAddress(), Args,
318 false, CallOrInvoke);
323 (void)getLValueForThis();
327 if (TrivialAssignment) {
336 ? TrivialAssignmentRHS
344 DevirtualizedMethod ? DevirtualizedMethod : MD;
346 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl))
347 FInfo = &
CGM.getTypes().arrangeCXXStructorDeclaration(
350 FInfo = &
CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl);
352 llvm::FunctionType *Ty =
CGM.getTypes().GetFunctionType(*FInfo);
363 if (
const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
364 auto *IOA = CMCE->getImplicitObjectArgument();
366 if (IsImplicitObjectCXXThis)
367 SkippedChecks.
set(SanitizerKind::Alignment,
true);
369 SkippedChecks.
set(SanitizerKind::Null,
true);
375 This.emitRawPointer(*
this),
376 C.getCanonicalTagType(CalleeDecl->
getParent()),
385 bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod;
389 "Destructor shouldn't have explicit parameters");
390 assert(
ReturnValue.isNull() &&
"Destructor shouldn't have return value");
391 if (UseVirtualCall) {
392 CGM.getCXXABI().EmitVirtualDestructorCall(
398 if (
getLangOpts().AppleKext && Dtor->isVirtual() && HasQualifier)
400 else if (!DevirtualizedMethod)
408 IsArrow ?
Base->getType()->getPointeeType() :
Base->getType();
420 if (UseVirtualCall) {
423 if (
SanOpts.has(SanitizerKind::CFINVCall) &&
427 std::tie(VTable, RD) =
CGM.getCXXABI().LoadVTablePtr(
434 else if (!DevirtualizedMethod)
446 CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
447 *
this, CalleeDecl,
This.getAddress(), UseVirtualCall);
448 This.setAddress(NewThisAddr);
453 nullptr,
QualType(), CE, RtlArgs, CallOrInvoke);
459 llvm::CallBase **CallOrInvoke) {
467 const auto *RD = MPT->getMostRecentCXXRecordDecl();
484 llvm::Value *ThisPtrForCall =
nullptr;
485 CGCallee Callee =
CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(
486 *
this, BO,
This, ThisPtrForCall, MemFnPtr, MPT);
499 return EmitCall(
CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required,
510 "Trying to emit a member call expr on a static method!");
513 false, E->
getArg(0), CallOrInvoke);
518 llvm::CallBase **CallOrInvoke) {
522 return CGM.getCUDARuntime().EmitCUDADeviceKernelCallExpr(
524 return CGM.getCUDARuntime().EmitCUDAKernelCallExpr(*
this, E,
ReturnValue,
547 std::vector<CharUnits> VBPtrOffsets =
549 for (
CharUnits VBPtrOffset : VBPtrOffsets) {
551 if (VBPtrOffset >= NVSize)
553 std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val();
554 CharUnits LastStoreOffset = LastStore.first;
556 CharUnits SplitBeforeOffset = LastStoreOffset;
557 CharUnits SplitBeforeSize = VBPtrOffset - SplitBeforeOffset;
558 assert(!SplitBeforeSize.
isNegative() &&
"negative store size!");
559 if (!SplitBeforeSize.
isZero())
560 Stores.emplace_back(SplitBeforeOffset, SplitBeforeSize);
562 CharUnits SplitAfterOffset = VBPtrOffset + VBPtrWidth;
563 CharUnits SplitAfterSize = NVSize - SplitAfterOffset;
564 assert(!SplitAfterSize.
isNegative() &&
"negative store size!");
565 if (!SplitAfterSize.
isZero())
566 Stores.emplace_back(SplitAfterOffset, SplitAfterSize);
576 if (!NullConstantForBase->isNullValue()) {
577 llvm::GlobalVariable *NullVariable =
new llvm::GlobalVariable(
579 true, llvm::GlobalVariable::PrivateLinkage,
580 NullConstantForBase, Twine());
584 NullVariable->setAlignment(Align.
getAsAlign());
589 for (std::pair<CharUnits, CharUnits> Store : Stores) {
592 llvm::Value *StoreSizeVal = CGF.
CGM.
getSize(StoreSize);
603 for (std::pair<CharUnits, CharUnits> Store : Stores) {
606 llvm::Value *StoreSizeVal = CGF.
CGM.
getSize(StoreSize);
609 CGF.
Builder.getInt8(0), StoreSizeVal);
616 assert(!Dest.
isIgnored() &&
"Must have a destination!");
661 bool ForVirtualBase =
false;
676 ForVirtualBase =
true;
691 Exp = E->getSubExpr();
693 "EmitSynthesizedCXXCopyCtor - unknown copy ctor expr");
706 "EmitSynthesizedCXXCopyCtor - Copied-in Array");
725 unsigned minElements,
726 llvm::Value *&numElements,
727 llvm::Value *&sizeWithoutCookie) {
734 return sizeWithoutCookie;
738 unsigned sizeWidth = CGF.
SizeTy->getBitWidth();
741 llvm::APInt cookieSize(sizeWidth,
760 (*e->
getArraySize())->getType()->isSignedIntegerOrEnumerationType();
761 llvm::IntegerType *numElementsType =
763 unsigned numElementsWidth = numElementsType->getBitWidth();
766 llvm::APInt arraySizeMultiplier(sizeWidth, 1);
769 type = CAT->getElementType();
770 arraySizeMultiplier *= CAT->getSize();
774 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.
getQuantity());
775 typeSizeMultiplier *= arraySizeMultiplier;
782 if (llvm::ConstantInt *numElementsC =
783 dyn_cast<llvm::ConstantInt>(numElements)) {
784 const llvm::APInt &count = numElementsC->getValue();
786 bool hasAnyOverflow =
false;
789 if (isSigned && count.isNegative())
790 hasAnyOverflow =
true;
795 else if (numElementsWidth > sizeWidth &&
796 numElementsWidth - sizeWidth > count.countl_zero())
797 hasAnyOverflow =
true;
800 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
804 if (adjustedCount.ult(minElements))
805 hasAnyOverflow =
true;
811 llvm::ConstantInt::get(CGF.
SizeTy, adjustedCount * arraySizeMultiplier);
815 llvm::APInt allocationSize =
816 adjustedCount.umul_ov(typeSizeMultiplier, overflow);
817 hasAnyOverflow |= overflow;
820 if (cookieSize != 0) {
823 sizeWithoutCookie = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
825 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
826 hasAnyOverflow |= overflow;
830 if (hasAnyOverflow) {
831 size = llvm::Constant::getAllOnesValue(CGF.
SizeTy);
833 size = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
851 llvm::Value *hasOverflow =
nullptr;
856 if (numElementsWidth > sizeWidth) {
857 llvm::APInt threshold =
858 llvm::APInt::getOneBitSet(numElementsWidth, sizeWidth);
860 llvm::Value *thresholdV =
861 llvm::ConstantInt::get(numElementsType, threshold);
863 hasOverflow = CGF.
Builder.CreateICmpUGE(numElements, thresholdV);
864 numElements = CGF.
Builder.CreateTrunc(numElements, CGF.
SizeTy);
867 }
else if (isSigned) {
868 if (numElementsWidth < sizeWidth)
869 numElements = CGF.
Builder.CreateSExt(numElements, CGF.
SizeTy);
876 if (typeSizeMultiplier == 1)
877 hasOverflow = CGF.
Builder.CreateICmpSLT(
878 numElements, llvm::ConstantInt::get(CGF.
SizeTy, minElements));
881 }
else if (numElementsWidth < sizeWidth) {
882 numElements = CGF.
Builder.CreateZExt(numElements, CGF.
SizeTy);
885 assert(numElements->getType() == CGF.
SizeTy);
890 hasOverflow = CGF.
Builder.CreateICmpULT(
891 numElements, llvm::ConstantInt::get(CGF.
SizeTy, minElements));
892 }
else if (numElementsWidth > sizeWidth) {
896 hasOverflow = CGF.
Builder.CreateOr(
899 numElements, llvm::ConstantInt::get(CGF.
SizeTy, minElements)));
912 if (typeSizeMultiplier != 1) {
913 llvm::Function *umul_with_overflow =
917 llvm::ConstantInt::get(CGF.
SizeTy, typeSizeMultiplier);
918 llvm::Value *result =
919 CGF.
Builder.CreateCall(umul_with_overflow, {size, tsmV});
921 llvm::Value *overflowed = CGF.
Builder.CreateExtractValue(result, 1);
923 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
925 hasOverflow = overflowed;
927 size = CGF.
Builder.CreateExtractValue(result, 0);
930 if (arraySizeMultiplier != 1) {
933 if (typeSize.
isOne()) {
934 assert(arraySizeMultiplier == typeSizeMultiplier);
940 llvm::ConstantInt::get(CGF.
SizeTy, arraySizeMultiplier);
941 numElements = CGF.
Builder.CreateMul(numElements, asmV);
946 assert(arraySizeMultiplier == 1);
950 if (cookieSize != 0) {
951 sizeWithoutCookie = size;
953 llvm::Function *uadd_with_overflow =
956 llvm::Value *cookieSizeV = llvm::ConstantInt::get(CGF.
SizeTy, cookieSize);
957 llvm::Value *result =
958 CGF.
Builder.CreateCall(uadd_with_overflow, {size, cookieSizeV});
960 llvm::Value *overflowed = CGF.
Builder.CreateExtractValue(result, 1);
962 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
964 hasOverflow = overflowed;
966 size = CGF.
Builder.CreateExtractValue(result, 0);
973 size = CGF.
Builder.CreateSelect(
974 hasOverflow, llvm::Constant::getAllOnesValue(CGF.
SizeTy), size);
978 sizeWithoutCookie = size;
980 assert(sizeWithoutCookie &&
"didn't set sizeWithoutCookie?");
1008 llvm_unreachable(
"bad evaluation kind");
1013 Address BeginPtr, llvm::Value *NumElements,
1014 llvm::Value *AllocSizeWithoutCookie) {
1022 unsigned InitListElements = 0;
1028 bool pushedCleanup =
false;
1035 auto TryMemsetInitialization = [&]() ->
bool {
1038 if (!
CGM.getTypes().isZeroInitializable(ElementType))
1045 auto *RemainingSize = AllocSizeWithoutCookie;
1046 if (InitListElements) {
1048 auto *InitializedSize = llvm::ConstantInt::get(
1049 RemainingSize->getType(),
1050 getContext().getTypeSizeInChars(ElementType).getQuantity() *
1052 RemainingSize =
Builder.CreateSub(RemainingSize, InitializedSize);
1056 Builder.CreateMemSet(CurPtr,
Builder.getInt8(0), RemainingSize,
false);
1064 const Expr *IgnoreParen =
nullptr;
1066 IgnoreParen =
Init->IgnoreParenImpCasts();
1067 CPLIE = dyn_cast<CXXParenListInitExpr>(IgnoreParen);
1068 SL = dyn_cast<StringLiteral>(IgnoreParen);
1069 OCEE = dyn_cast<ObjCEncodeExpr>(IgnoreParen);
1073 if (ILE || CPLIE || SL || OCEE) {
1093 CurPtr =
Builder.CreateConstInBoundsGEP(CurPtr, InitListElements,
1097 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1098 if (!ConstNum || !ConstNum->equalsInt(InitListElements)) {
1099 bool OK = TryMemsetInitialization();
1101 assert(OK &&
"couldn't memset character type?");
1128 llvm::Instruction *DominatingIP =
1133 EndOfInit, ElementType, ElementAlign,
1136 .AddAuxAllocas(AllocaTracker.Take());
1138 {
EHStack.stable_begin(), DominatingIP});
1139 pushedCleanup =
true;
1144 auto AdvanceToNextElement = [&]() {
1152 for (
const Expr *IE : InitExprs) {
1163 const auto *EmbedS = dyn_cast<EmbedExpr>(IE->IgnoreParenImpCasts());
1164 if (EmbedS && EmbedS->getDataElementCount() > 1) {
1166 llvm::Type *DataTy =
ConvertType(EmbedS->getType());
1167 for (
unsigned I = EmbedS->getStartingElementPos(),
1168 End = I + EmbedS->getDataElementCount();
1171 llvm::ConstantInt::get(DataTy, SL->
getCodeUnit(I)),
1172 EmbedS->getType(), ElementType, EmbedS->getLocation());
1175 AdvanceToNextElement();
1184 AdvanceToNextElement();
1193 while (
Init &&
Init->getType()->isConstantArrayType()) {
1194 auto *SubILE = dyn_cast<InitListExpr>(
Init);
1197 assert(SubILE->getNumInits() == 0 &&
"explicit inits in array filler?");
1198 Init = SubILE->getArrayFiller();
1207 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1208 if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
1212 assert(
Init &&
"have trailing elements to initialize but no initializer");
1224 if (TryMemsetInitialization())
1236 if (InitListElements)
1237 NumElements =
Builder.CreateSub(
1239 llvm::ConstantInt::get(NumElements->getType(), InitListElements));
1242 CCE->requiresZeroInitialization());
1243 if (
getContext().getTargetInfo().emitVectorDeletingDtors(
1246 if (Dtor && Dtor->isVirtual())
1247 CGM.requireVectorDestructorDefinition(Ctor->
getParent());
1255 if (TryMemsetInitialization())
1266 assert(
getContext().hasSameUnqualifiedType(ElementType,
Init->getType()) &&
1267 "got wrong type of element to initialize");
1270 if (
auto *ILE = dyn_cast<InitListExpr>(
Init))
1271 if (ILE->
getNumInits() == 0 && TryMemsetInitialization())
1276 if (
auto *ILE = dyn_cast<InitListExpr>(
Init)) {
1277 if (
const RecordType *RType =
1279 if (RType->getDecl()->isStruct()) {
1281 unsigned NumElements = 0;
1282 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1283 NumElements = CXXRD->getNumBases();
1284 for (
auto *Field : RD->
fields())
1285 if (!Field->isUnnamedBitField())
1289 for (
unsigned i = 0, e = ILE->
getNumInits(); i != e; ++i)
1292 if (ILE->
getNumInits() == NumElements && TryMemsetInitialization())
1299 llvm::BasicBlock *EntryBB =
Builder.GetInsertBlock();
1304 llvm::Value *EndPtr =
Builder.CreateInBoundsGEP(
1312 EndPtr,
"array.isempty");
1313 Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
1320 llvm::PHINode *CurPtrPhi =
1332 llvm::Instruction *DominatingIP =
1338 {
EHStack.stable_begin(), DominatingIP});
1349 llvm::Value *NextPtr =
Builder.CreateConstInBoundsGEP1_32(
1354 llvm::Value *IsEnd =
Builder.CreateICmpEQ(NextPtr, EndPtr,
"array.atend");
1355 Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
1356 CurPtrPhi->addIncoming(NextPtr,
Builder.GetInsertBlock());
1362 QualType ElementType, llvm::Type *ElementTy,
1363 Address NewPtr, llvm::Value *NumElements,
1364 llvm::Value *AllocSizeWithoutCookie) {
1368 AllocSizeWithoutCookie);
1380 llvm::Constant *CalleeOverride =
nullptr) {
1381 llvm::CallBase *CallOrInvoke;
1382 llvm::Constant *CalleePtr =
1395 llvm::Function *Fn = dyn_cast<llvm::Function>(CalleePtr);
1397 if (Fn->hasFnAttribute(llvm::Attribute::NoBuiltin))
1398 CallOrInvoke->addFnAttr(llvm::Attribute::Builtin);
1405 CallOrInvoke->setMemoryEffects(
1406 llvm::MemoryEffects::inaccessibleOrErrnoMemOnly(
1407 llvm::ModRefInfo::ModRef, llvm::ModRefInfo::Mod));
1425 if (
auto *FD = dyn_cast<FunctionDecl>(
Decl))
1428 if (
auto *CB = dyn_cast_if_present<llvm::CallBase>(RV.
getScalarVal())) {
1429 if (
SanOpts.has(SanitizerKind::AllocToken)) {
1436 llvm_unreachable(
"predeclared global operator new/delete is missing");
1443template <
typename Traits>
1444class CallDeleteDuringNew final :
public EHScopeStack::Cleanup {
1446 typedef typename Traits::ValueTy ValueTy;
1448 typedef typename Traits::RValueTy RValueTy;
1449 struct PlacementArg {
1454 unsigned NumPlacementArgs : 30;
1456 unsigned PassAlignmentToPlacementDelete : 1;
1458 RValueTy TypeIdentity;
1463 PlacementArg *getPlacementArgs() {
1464 return reinterpret_cast<PlacementArg *
>(
this + 1);
1468 static size_t getExtraSize(
size_t NumPlacementArgs) {
1469 return NumPlacementArgs *
sizeof(PlacementArg);
1472 CallDeleteDuringNew(
size_t NumPlacementArgs,
1473 const FunctionDecl *OperatorDelete, RValueTy TypeIdentity,
1474 ValueTy Ptr, ValueTy AllocSize,
1475 const ImplicitAllocationParameters &IAP,
1476 CharUnits AllocAlign)
1477 : NumPlacementArgs(NumPlacementArgs),
1479 OperatorDelete(OperatorDelete), TypeIdentity(TypeIdentity),
Ptr(
Ptr),
1480 AllocSize(AllocSize), AllocAlign(AllocAlign) {}
1482 void setPlacementArg(
unsigned I, RValueTy Arg, QualType
Type) {
1483 assert(I < NumPlacementArgs &&
"index out of range");
1484 getPlacementArgs()[I] = {Arg,
Type};
1487 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1488 const auto *FPT = OperatorDelete->getType()->castAs<FunctionProtoType>();
1489 CallArgList DeleteArgs;
1490 unsigned FirstNonTypeArg = 0;
1492 if (OperatorDelete->isTypeAwareOperatorNewOrDelete()) {
1493 TypeAwareDeallocation = TypeAwareAllocationMode::Yes;
1494 QualType SpecializedTypeIdentity = FPT->getParamType(0);
1496 DeleteArgs.add(Traits::get(CGF, TypeIdentity), SpecializedTypeIdentity);
1500 DeleteArgs.add(Traits::get(CGF, Ptr), FPT->getParamType(FirstNonTypeArg));
1503 UsualDeleteParams Params;
1504 if (NumPlacementArgs) {
1514 Params = OperatorDelete->getUsualDeleteParams();
1518 "should not call destroying delete in a new-expression");
1522 DeleteArgs.add(Traits::get(CGF, AllocSize),
1530 DeleteArgs.add(
RValue::get(llvm::ConstantInt::get(
1535 for (
unsigned I = 0; I != NumPlacementArgs; ++I) {
1536 auto Arg = getPlacementArgs()[I];
1537 DeleteArgs.add(Traits::get(CGF, Arg.ArgValue), Arg.ArgType);
1550 llvm::Value *AllocSize,
CharUnits AllocAlign,
1557 struct DirectCleanupTraits {
1558 typedef llvm::Value *ValueTy;
1564 typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
1571 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1572 Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty);
1585 struct ConditionalCleanupTraits {
1589 return V.restore(CGF);
1592 typedef CallDeleteDuringNew<ConditionalCleanupTraits> ConditionalCleanup;
1594 ConditionalCleanup *Cleanup =
1597 SavedTypeIdentity, SavedNewPtr, SavedAllocSize,
1600 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1601 Cleanup->setPlacementArg(
1617 unsigned minElements = 0;
1618 unsigned IndexOfAlignArg = 1;
1623 const Expr *IgnoreParen =
Init->IgnoreParenImpCasts();
1629 }
else if (ILE || CPLIE) {
1635 llvm::Value *numElements =
nullptr;
1636 llvm::Value *allocSizeWithoutCookie =
nullptr;
1638 *
this, E, minElements, numElements, allocSizeWithoutCookie);
1646 if (allocator->isReservedGlobalPlacementOperator()) {
1664 allocatorArgs.
add(
RValue::get(allocation, *
this), arg->getType());
1671 unsigned ParamsToSkip = 0;
1677 allocatorArgs.
add(TypeIdentityArg, SpecializedTypeIdentity);
1686 if (allocSize != allocSizeWithoutCookie) {
1688 allocAlign = std::max(allocAlign, cookieAlign);
1695 AlignValT = allocatorType->
getParamType(IndexOfAlignArg);
1698 "wrong type for alignment parameter");
1702 assert(allocator->isVariadic() &&
"can't pass alignment to allocator");
1716 if (
auto *newCall = dyn_cast<llvm::CallBase>(RV.
getScalarVal())) {
1719 CGDI->addHeapAllocSiteMetadata(newCall, allocType, E->
getExprLoc());
1721 if (
SanOpts.has(SanitizerKind::AllocToken)) {
1733 allocator->isReplaceableGlobalAllocationFunction()) {
1734 unsigned AllocatorAlign = llvm::bit_floor(std::min<uint64_t>(
1736 allocationAlign = std::max(
1737 allocationAlign,
getContext().toCharUnitsFromBits(AllocatorAlign));
1751 llvm::BasicBlock *nullCheckBB =
nullptr;
1752 llvm::BasicBlock *contBB =
nullptr;
1759 conditional.
begin(*
this);
1761 nullCheckBB =
Builder.GetInsertBlock();
1765 llvm::Value *isNull =
Builder.CreateIsNull(allocation,
"new.isnull");
1766 Builder.CreateCondBr(isNull, contBB, notNullBB);
1773 llvm::Instruction *cleanupDominator =
nullptr;
1780 const auto *FPT = ConstructExpr->getConstructor()
1783 if (!FPT->isNothrow())
1785 diag::err_seh_object_unwinding);
1789 allocAlign, allocatorArgs);
1790 operatorDeleteCleanup =
EHStack.stable_begin();
1798 assert(allocSize == llvm::Constant::getAllOnesValue(
SizeTy) ||
1799 ((allocSize == allocSizeWithoutCookie) ==
1801 if (allocSize != allocSizeWithoutCookie) {
1803 allocation =
CGM.getCXXABI().InitializeArrayCookie(
1804 *
this, allocation, numElements, E, allocType);
1814 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1815 allocator->isReservedGlobalPlacementOperator())
1816 result =
Builder.CreateLaunderInvariantGroup(result);
1824 SkippedChecks.
set(SanitizerKind::Null, nullCheck);
1827 result, allocType, result.
getAlignment(), SkippedChecks,
1831 allocSizeWithoutCookie);
1836 if (operatorDeleteCleanup.
isValid()) {
1838 cleanupDominator->eraseFromParent();
1842 conditional.
end(*
this);
1844 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
1847 llvm::PHINode *PHI =
Builder.CreatePHI(resultPtr->getType(), 2);
1848 PHI->addIncoming(resultPtr, notNullBB);
1849 PHI->addIncoming(llvm::Constant::getNullValue(resultPtr->getType()),
1859 llvm::Value *DeletePtr,
QualType DeleteTy,
1860 llvm::Value *NumElements,
1862 llvm::Constant *CalleeOverride) {
1863 assert((!NumElements && CookieSize.
isZero()) ||
1870 auto ParamTypeIt = DeleteFTy->param_type_begin();
1872 std::optional<llvm::AllocaInst *> TagAlloca;
1873 auto EmitTag = [&](
QualType TagType,
const char *TagName) {
1876 CharUnits Align =
CGM.getNaturalTypeAlignment(TagType);
1878 TagAllocation->setAlignment(Align.
getAsAlign());
1881 TagAlloca = TagAllocation;
1886 EmitTag(*ParamTypeIt++,
"typeaware.delete.tag");
1894 EmitTag(*ParamTypeIt++,
"destroying.delete.tag");
1898 QualType SizeType = *ParamTypeIt++;
1900 llvm::Value *Size = llvm::ConstantInt::get(
ConvertType(SizeType),
1905 Size =
Builder.CreateMul(Size, NumElements);
1908 if (!CookieSize.
isZero())
1917 QualType AlignValType = *ParamTypeIt++;
1921 llvm::Value *Align = llvm::ConstantInt::get(
ConvertType(AlignValType),
1926 assert(ParamTypeIt == DeleteFTy->param_type_end() &&
1927 "unknown parameter to usual delete function");
1934 if (TagAlloca && (*TagAlloca)->use_empty())
1935 (*TagAlloca)->eraseFromParent();
1939struct CallObjectDelete final : EHScopeStack::Cleanup {
1944 CallObjectDelete(llvm::Value *Ptr,
const FunctionDecl *OperatorDelete,
1946 : Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
1955 const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr,
1958 OperatorDelete, ElementType);
1968 auto *Dtor = ElementType->getAsCXXRecordDecl()->getDestructor();
1969 if (Dtor && Dtor->isVirtual())
1980 assert(Dtor && Dtor->isVirtual() &&
"virtual dtor is expected");
1982 if (
auto *MaybeDevirtualizedDtor = dyn_cast_or_null<CXXDestructorDecl>(
1983 Dtor->getDevirtualizedMethod(DBase, LO.AppleKext))) {
1989 return MaybeDevirtualizedDtor;
2005 llvm::BasicBlock *UnconditionalDeleteBlock) {
2015 assert(!OperatorDelete->isDestroyingOperatorDelete());
2020 if (
const auto *RD = ElementType->getAsCXXRecordDecl()) {
2021 if (RD->hasDefinition() && !RD->hasTrivialDestructor()) {
2022 Dtor = RD->getDestructor();
2024 if (Dtor->isVirtual()) {
2025 if (
auto *DevirtualizedDtor =
2027 Dtor = DevirtualizedDtor;
2040 CGF.
EHStack.pushCleanup<CallObjectDelete>(
2046 false, Ptr, ElementType);
2047 else if (
auto Lifetime = ElementType.getObjCLifetime()) {
2066 CGF.
EmitBlock(UnconditionalDeleteBlock);
2077struct CallArrayDelete final : EHScopeStack::Cleanup {
2079 const FunctionDecl *OperatorDelete;
2080 llvm::Value *NumElements;
2081 QualType ElementType;
2082 CharUnits CookieSize;
2084 CallArrayDelete(llvm::Value *Ptr,
const FunctionDecl *OperatorDelete,
2085 llvm::Value *NumElements, QualType ElementType,
2086 CharUnits CookieSize)
2087 :
Ptr(
Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
2088 ElementType(ElementType), CookieSize(CookieSize) {}
2090 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2091 CGF.
EmitDeleteCall(OperatorDelete, Ptr, ElementType, NumElements,
2100 llvm::Value *numElements =
nullptr;
2101 llvm::Value *allocatedPtr =
nullptr;
2104 numElements, allocatedPtr, cookieSize);
2106 assert(allocatedPtr &&
"ReadArrayCookie didn't set allocated pointer");
2111 operatorDelete, numElements,
2112 elementType, cookieSize);
2116 assert(numElements &&
"no element count for a type with a destructor!");
2124 deletedPtr.
getElementType(), arrayBegin, numElements,
"delete.end");
2157 CGM.noteDirectGlobalDelete();
2166 "global ::delete should resolve to a namespace-scope "
2168 CGM.getOrCreateMSVCGlobalDeleteWrapper(OD);
2186 Ptr.setKnownNonNull();
2203 CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2204 CGM.getContext().getLangOpts())) {
2206 auto *Dtor = RD->getDestructor();
2207 if (Dtor && Dtor->isVirtual()) {
2212 llvm::Value *NumElements =
nullptr;
2213 llvm::Value *AllocatedPtr =
nullptr;
2219 CGM.getCXXABI().ReadArrayCookie(*
this, Ptr, E, DeleteTy, NumElements,
2220 AllocatedPtr, CookieSize);
2223 llvm::Value *IsEmpty =
Builder.CreateICmpEQ(
2224 NumElements, llvm::ConstantInt::get(CondTy, 0));
2225 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
2230 EmitDeleteCall(OperatorDelete, AllocatedPtr, DeleteTy, NumElements,
2235 CGM.getCXXABI().emitVirtualObjectDelete(*
this, E, Ptr, DeleteTy,
2254 bool HasNullCheck) {
2265 ThisPtr, SrcRecordTy);
2272 llvm::BasicBlock *BadTypeidBlock =
2294 LangAS GlobAS =
CGM.GetGlobalVarAddressSpace(
nullptr);
2296 auto MaybeASCast = [=](llvm::Constant *
TypeInfo) {
2309 QualType OperandTy = Operand->getType();
2319 return CGM.getCXXABI().EmitTypeid(*
this, OperandTy, ThisPtr, PtrTy);
2323 return MaybeASCast(
CGM.GetAddrOfRTTIDescriptor(OperandTy));
2330 return llvm::Constant::getNullValue(DestLTy);
2337 CGF.
Builder.ClearInsertionPoint();
2338 return llvm::PoisonValue::get(DestLTy);
2343 CGM.EmitExplicitCastExprType(DCE,
this);
2354 if (IsDynamicCastToVoid) {
2361 SrcRecordTy = SrcTy;
2375 if (!
Builder.GetInsertBlock())
2381 assert(SrcRecordTy->
isRecordType() &&
"source type must be a record type!");
2385 bool IsExact = !IsDynamicCastToVoid &&
2386 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2388 CGM.getCXXABI().shouldEmitExactDynamicCast(DestRecordTy);
2390 std::optional<CGCXXABI::ExactDynamicCastInfo> ExactCastInfo;
2392 ExactCastInfo =
CGM.getCXXABI().getExactDynamicCastInfo(SrcRecordTy, DestTy,
2394 if (!ExactCastInfo) {
2396 if (!
Builder.GetInsertBlock())
2405 bool ShouldNullCheckSrcValue =
2406 IsExact ||
CGM.getCXXABI().shouldDynamicCastCallBeNullChecked(
2409 llvm::BasicBlock *CastNull =
nullptr;
2410 llvm::BasicBlock *CastNotNull =
nullptr;
2413 if (ShouldNullCheckSrcValue) {
2423 if (IsDynamicCastToVoid) {
2424 Value =
CGM.getCXXABI().emitDynamicCastToVoid(*
this, ThisAddr, SrcRecordTy);
2425 }
else if (IsExact) {
2428 Value =
CGM.getCXXABI().emitExactDynamicCast(
2429 *
this, ThisAddr, SrcRecordTy, DestTy, DestRecordTy, *ExactCastInfo,
2433 "destination type must be a record type!");
2434 Value =
CGM.getCXXABI().emitDynamicCastCall(*
this, ThisAddr, SrcRecordTy,
2435 DestTy, DestRecordTy, CastEnd);
2437 CastNotNull =
Builder.GetInsertBlock();
2439 llvm::Value *NullValue =
nullptr;
2440 if (ShouldNullCheckSrcValue) {
2445 CastNull =
Builder.GetInsertBlock();
2454 PHI->addIncoming(
Value, CastNotNull);
2455 PHI->addIncoming(NullValue, CastNull);
static MemberCallInfo commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE, CallArgList &Args, CallArgList *RtlArgs)
static llvm::Value * EmitDynamicCastToNull(CodeGenFunction &CGF, QualType DestTy)
static CXXDestructorDecl * TryDevirtualizeDtorCall(const CXXDeleteExpr *E, CXXDestructorDecl *Dtor, const LangOptions &LO)
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.
static void EmitNullBaseClassInitialization(CodeGenFunction &CGF, Address DestPtr, const CXXRecordDecl *Base)
static Address EmitTypeidOperand(CodeGenFunction &CGF, const Expr *E, bool HasNullCheck)
static bool EmitObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, llvm::BasicBlock *UnconditionalDeleteBlock)
Emit the code for deleting a single object.
static CXXRecordDecl * getCXXRecord(const Expr *E)
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.
static CharUnits CalculateCookiePadding(CodeGenFunction &CGF, const CXXNewExpr *E)
static void EmitArrayDelete(CodeGenFunction &CGF, const CXXDeleteExpr *E, Address deletedPtr, QualType elementType)
Emit the code for deleting an array of objects.
static RValue EmitNewDeleteCall(CodeGenFunction &CGF, const FunctionDecl *CalleeDecl, const FunctionProtoType *CalleeType, const CallArgList &Args, llvm::Constant *CalleeOverride=nullptr)
Emit a call to an operator new or operator delete function, as implicitly created by new-expressions ...
static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, QualType AllocType, Address NewPtr, AggValueSlot::Overlap_t MayOverlap)
static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E, QualType ElementType, llvm::Type *ElementTy, Address NewPtr, llvm::Value *NumElements, llvm::Value *AllocSizeWithoutCookie)
static llvm::Value * EmitCXXNewAllocSize(CodeGenFunction &CGF, const CXXNewExpr *e, unsigned minElements, llvm::Value *&numElements, llvm::Value *&sizeWithoutCookie)
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.
static uint64_t getConstantArrayElementCount(const ConstantArrayType *CA)
Return number of (potentially nested) constant array elements.
DiagnosticsEngine & getDiagnostics() const
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.
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
bool isGlobalDelete() 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.
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 isMemcpyEquivalentSpecialMember(const ASTContext &Ctx) const
Returns whether this is a copy/move constructor or assignment operator that can be implemented as a m...
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.
SourceLocation getBeginLoc() const
bool passAlignment() const
Indicates whether the required alignment should be implicitly passed to the allocation function.
FunctionDecl * getOperatorDelete() const
unsigned getNumPlacementArgs() const
const CXXConstructExpr * getConstructExpr() const
Returns the CXXConstructExpr from this new-expression, or null.
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 hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool isDynamicClass() const
bool hasDefinition() 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.
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
Test whether the quantity is less than zero.
bool isZero() const
Test whether the quantity equals zero.
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
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
Test whether the quantity equals one.
static CharUnits 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.
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 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)
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
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)
RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, bool HasQualifier, NestedNameSpecifier Qualifier, bool IsArrow, const Expr *Base, llvm::CallBase **CallOrInvoke)
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)
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)
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_Store
Checking the destination of a store. Must be suitably sized and aligned.
@ 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.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
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.
bool currentFunctionUsesSEHTry() const
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
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)
RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
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)
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,...
RValue EmitAnyExprToTemp(const Expr *E)
EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will always be accessible even if...
ASTContext & getContext() const
LValue EmitHLSLOutArgExpr(const HLSLOutArgExpr *E, CallArgList &Args, QualType Ty, bool IsImplicitObject=false)
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)
llvm::Type * ConvertTypeForMem(QualType T)
void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, Address This, Address Src, const CXXConstructExpr *E)
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,...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
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)
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,...
const FunctionDecl * getCurrentFunctionDecl() const
static bool IsWrappedCXXThis(const Expr *E)
Check if E is a C++ "this" pointer wrapped in value-preserving casts.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits(), llvm::Constant *CalleeOverride=nullptr)
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)
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
void PopCleanupBlock(bool FallThroughIsBranchThrough=false, bool ForDeactivation=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
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...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Value * EmitCXXTypeidExpr(const CXXTypeidExpr *E)
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.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall, const FunctionDecl *ABIInfoFD)
Figure out the rules for calling a function with the given formal type using the given arguments.
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.
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,...
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.
bool isAnyOperatorNew() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
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:
UsualDeleteParams getUsualDeleteParams() const
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
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...
unsigned getNumInitsWithEmbedExpanded() const
getNumInits but if the list has an EmbedExpr inside includes full length of embedded data.
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
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
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.
uint32_t getCodeUnit(size_t I) const
Return the code unit at the given position.
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<specific type>.
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<specific type>'.
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
Top level wrappers for InstallAPI frontend operations.
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.
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