22#include "llvm/IR/Intrinsics.h"
25using namespace CodeGen;
28struct MemberCallInfo {
37 llvm::Value *
This, llvm::Value *ImplicitParam,
40 auto *MD = cast<CXXMethodDecl>(GD.
getDecl());
42 assert(CE ==
nullptr || isa<CXXMemberCallExpr>(CE) ||
43 isa<CXXOperatorCallExpr>(CE));
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);
95 Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize);
104 llvm::CallBase **CallOrInvoke) {
109 "Pointer/Object mixup");
113 if (SrcAS != DstAS) {
121 ImplicitParamTy, CE, Args,
nullptr);
130 QualType DestroyedType =
E->getDestroyedType();
135 Expr *BaseExpr =
E->getBase();
143 BaseQuals = PTy->getPointeeType().getQualifiers();
190 llvm::CallBase **CallOrInvoke) {
193 if (isa<BinaryOperator>(callee))
196 const MemberExpr *ME = cast<MemberExpr>(callee);
213 HasQualifier, Qualifier, IsArrow,
220 const Expr *
Base, llvm::CallBase **CallOrInvoke) {
221 assert(isa<CXXMemberCallExpr>(CE) || isa<CXXOperatorCallExpr>(CE));
224 bool CanUseVirtualCall = MD->
isVirtual() && !HasQualifier;
227 if (CanUseVirtualCall &&
231 assert(DevirtualizedMethod);
233 const Expr *Inner =
Base->IgnoreParenBaseCasts();
241 DevirtualizedMethod =
nullptr;
251 DevirtualizedMethod =
nullptr;
255 bool TrivialForCodegen =
257 bool TrivialAssignment =
266 LValue TrivialAssignmentRHS;
267 if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
268 if (OCE->isAssignmentOp()) {
269 if (TrivialAssignment) {
272 RtlArgs = &RtlArgStorage;
295 assert(
ReturnValue.isNull() &&
"Constructor shouldn't have return value");
303 false,
This.getAddress(), Args,
305 false, CallOrInvoke);
309 if (TrivialForCodegen) {
310 if (isa<CXXDestructorDecl>(MD))
313 if (TrivialAssignment) {
319 LValue RHS = isa<CXXOperatorCallExpr>(CE)
320 ? TrivialAssignmentRHS
327 "unknown trivial member function");
332 DevirtualizedMethod ? DevirtualizedMethod : MD;
334 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl))
351 if (
const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
352 auto *IOA = CMCE->getImplicitObjectArgument();
354 if (IsImplicitObjectCXXThis)
355 SkippedChecks.
set(SanitizerKind::Alignment,
true);
356 if (IsImplicitObjectCXXThis || isa<DeclRefExpr>(IOA))
357 SkippedChecks.
set(SanitizerKind::Null,
true);
362 This.emitRawPointer(*
this),
363 C.getCanonicalTagType(CalleeDecl->
getParent()),
372 bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod;
376 "Destructor shouldn't have explicit parameters");
377 assert(
ReturnValue.isNull() &&
"Destructor shouldn't have return value");
378 if (UseVirtualCall) {
381 cast<CXXMemberCallExpr>(CE), CallOrInvoke);
385 if (
getLangOpts().AppleKext && Dtor->isVirtual() && HasQualifier)
387 else if (!DevirtualizedMethod)
395 IsArrow ?
Base->getType()->getPointeeType() :
Base->getType();
407 if (UseVirtualCall) {
421 else if (!DevirtualizedMethod)
434 *
this, CalleeDecl,
This.getAddress(), UseVirtualCall);
435 This.setAddress(NewThisAddr);
440 nullptr,
QualType(), CE, RtlArgs, CallOrInvoke);
446 llvm::CallBase **CallOrInvoke) {
454 const auto *RD = MPT->getMostRecentCXXRecordDecl();
471 llvm::Value *ThisPtrForCall =
nullptr;
474 ThisPtrForCall, MemFnPtr, MPT);
497 "Trying to emit a member call expr on a static method!");
500 false,
E->getArg(0), CallOrInvoke);
505 llvm::CallBase **CallOrInvoke) {
529 std::vector<CharUnits> VBPtrOffsets =
531 for (
CharUnits VBPtrOffset : VBPtrOffsets) {
533 if (VBPtrOffset >= NVSize)
535 std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val();
536 CharUnits LastStoreOffset = LastStore.first;
537 CharUnits LastStoreSize = LastStore.second;
539 CharUnits SplitBeforeOffset = LastStoreOffset;
540 CharUnits SplitBeforeSize = VBPtrOffset - SplitBeforeOffset;
541 assert(!SplitBeforeSize.
isNegative() &&
"negative store size!");
542 if (!SplitBeforeSize.
isZero())
543 Stores.emplace_back(SplitBeforeOffset, SplitBeforeSize);
545 CharUnits SplitAfterOffset = VBPtrOffset + VBPtrWidth;
546 CharUnits SplitAfterSize = LastStoreSize - SplitAfterOffset;
547 assert(!SplitAfterSize.
isNegative() &&
"negative store size!");
548 if (!SplitAfterSize.
isZero())
549 Stores.emplace_back(SplitAfterOffset, SplitAfterSize);
559 if (!NullConstantForBase->isNullValue()) {
560 llvm::GlobalVariable *NullVariable =
new llvm::GlobalVariable(
562 true, llvm::GlobalVariable::PrivateLinkage,
563 NullConstantForBase, Twine());
567 NullVariable->setAlignment(Align.
getAsAlign());
572 for (std::pair<CharUnits, CharUnits> Store : Stores) {
575 llvm::Value *StoreSizeVal = CGF.
CGM.
getSize(StoreSize);
586 for (std::pair<CharUnits, CharUnits> Store : Stores) {
589 llvm::Value *StoreSizeVal = CGF.
CGM.
getSize(StoreSize);
592 CGF.
Builder.getInt8(0), StoreSizeVal);
600 assert(!Dest.
isIgnored() &&
"Must have a destination!");
607 if (
E->requiresZeroInitialization() && !Dest.
isZeroed()) {
608 switch (
E->getConstructionKind()) {
626 if (
getLangOpts().ElideConstructors &&
E->isElidable()) {
632 const Expr *SrcObj =
E->getArg(0);
646 bool ForVirtualBase =
false;
649 switch (
E->getConstructionKind()) {
661 ForVirtualBase =
true;
676 Exp =
E->getSubExpr();
677 assert(isa<CXXConstructExpr>(Exp) &&
678 "EmitSynthesizedCXXCopyCtor - unknown copy ctor expr");
687 if (
E->requiresZeroInitialization())
691 &&
"EmitSynthesizedCXXCopyCtor - Copied-in Array");
702 if (
E->getOperatorNew()->isReservedGlobalPlacementOperator())
710 unsigned minElements,
711 llvm::Value *&numElements,
712 llvm::Value *&sizeWithoutCookie) {
719 return sizeWithoutCookie;
723 unsigned sizeWidth = CGF.
SizeTy->getBitWidth();
726 llvm::APInt cookieSize(sizeWidth,
736 assert(isa<llvm::IntegerType>(numElements->getType()));
745 = (*e->
getArraySize())->getType()->isSignedIntegerOrEnumerationType();
746 llvm::IntegerType *numElementsType
747 = cast<llvm::IntegerType>(numElements->getType());
748 unsigned numElementsWidth = numElementsType->getBitWidth();
751 llvm::APInt arraySizeMultiplier(sizeWidth, 1);
754 type = CAT->getElementType();
755 arraySizeMultiplier *= CAT->getSize();
759 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.
getQuantity());
760 typeSizeMultiplier *= arraySizeMultiplier;
767 if (llvm::ConstantInt *numElementsC =
768 dyn_cast<llvm::ConstantInt>(numElements)) {
769 const llvm::APInt &count = numElementsC->getValue();
771 bool hasAnyOverflow =
false;
774 if (isSigned && count.isNegative())
775 hasAnyOverflow =
true;
780 else if (numElementsWidth > sizeWidth &&
781 numElementsWidth - sizeWidth > count.countl_zero())
782 hasAnyOverflow =
true;
785 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
789 if (adjustedCount.ult(minElements))
790 hasAnyOverflow =
true;
795 numElements = llvm::ConstantInt::get(CGF.
SizeTy,
796 adjustedCount * arraySizeMultiplier);
800 llvm::APInt allocationSize
801 = adjustedCount.umul_ov(typeSizeMultiplier, overflow);
802 hasAnyOverflow |= overflow;
805 if (cookieSize != 0) {
808 sizeWithoutCookie = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
810 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
811 hasAnyOverflow |= overflow;
815 if (hasAnyOverflow) {
816 size = llvm::Constant::getAllOnesValue(CGF.
SizeTy);
818 size = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
836 llvm::Value *hasOverflow =
nullptr;
841 if (numElementsWidth > sizeWidth) {
842 llvm::APInt threshold =
843 llvm::APInt::getOneBitSet(numElementsWidth, sizeWidth);
845 llvm::Value *thresholdV
846 = llvm::ConstantInt::get(numElementsType, threshold);
848 hasOverflow = CGF.
Builder.CreateICmpUGE(numElements, thresholdV);
849 numElements = CGF.
Builder.CreateTrunc(numElements, CGF.
SizeTy);
852 }
else if (isSigned) {
853 if (numElementsWidth < sizeWidth)
854 numElements = CGF.
Builder.CreateSExt(numElements, CGF.
SizeTy);
861 if (typeSizeMultiplier == 1)
862 hasOverflow = CGF.
Builder.CreateICmpSLT(numElements,
863 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
866 }
else if (numElementsWidth < sizeWidth) {
867 numElements = CGF.
Builder.CreateZExt(numElements, CGF.
SizeTy);
870 assert(numElements->getType() == CGF.
SizeTy);
875 hasOverflow = CGF.
Builder.CreateICmpULT(numElements,
876 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
877 }
else if (numElementsWidth > sizeWidth) {
881 hasOverflow = CGF.
Builder.CreateOr(hasOverflow,
882 CGF.
Builder.CreateICmpULT(numElements,
883 llvm::ConstantInt::get(CGF.
SizeTy, minElements)));
896 if (typeSizeMultiplier != 1) {
897 llvm::Function *umul_with_overflow
901 llvm::ConstantInt::get(CGF.
SizeTy, typeSizeMultiplier);
902 llvm::Value *result =
903 CGF.
Builder.CreateCall(umul_with_overflow, {size, tsmV});
905 llvm::Value *overflowed = CGF.
Builder.CreateExtractValue(result, 1);
907 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
909 hasOverflow = overflowed;
911 size = CGF.
Builder.CreateExtractValue(result, 0);
914 if (arraySizeMultiplier != 1) {
917 if (typeSize.
isOne()) {
918 assert(arraySizeMultiplier == typeSizeMultiplier);
924 llvm::ConstantInt::get(CGF.
SizeTy, arraySizeMultiplier);
925 numElements = CGF.
Builder.CreateMul(numElements, asmV);
930 assert(arraySizeMultiplier == 1);
934 if (cookieSize != 0) {
935 sizeWithoutCookie = size;
937 llvm::Function *uadd_with_overflow
940 llvm::Value *cookieSizeV = llvm::ConstantInt::get(CGF.
SizeTy, cookieSize);
941 llvm::Value *result =
942 CGF.
Builder.CreateCall(uadd_with_overflow, {size, cookieSizeV});
944 llvm::Value *overflowed = CGF.
Builder.CreateExtractValue(result, 1);
946 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
948 hasOverflow = overflowed;
950 size = CGF.
Builder.CreateExtractValue(result, 0);
957 size = CGF.
Builder.CreateSelect(hasOverflow,
958 llvm::Constant::getAllOnesValue(CGF.
SizeTy),
963 sizeWithoutCookie = size;
965 assert(sizeWithoutCookie &&
"didn't set sizeWithoutCookie?");
995 llvm_unreachable(
"bad evaluation kind");
1000 Address BeginPtr, llvm::Value *NumElements,
1001 llvm::Value *AllocSizeWithoutCookie) {
1004 if (!
E->hasInitializer())
1009 unsigned InitListElements = 0;
1015 bool pushedCleanup =
false;
1022 auto TryMemsetInitialization = [&]() ->
bool {
1032 auto *RemainingSize = AllocSizeWithoutCookie;
1033 if (InitListElements) {
1035 auto *InitializedSize = llvm::ConstantInt::get(
1036 RemainingSize->getType(),
1037 getContext().getTypeSizeInChars(ElementType).getQuantity() *
1039 RemainingSize =
Builder.CreateSub(RemainingSize, InitializedSize);
1051 const Expr *IgnoreParen =
nullptr;
1053 IgnoreParen =
Init->IgnoreParenImpCasts();
1054 CPLIE = dyn_cast<CXXParenListInitExpr>(IgnoreParen);
1055 SL = dyn_cast<StringLiteral>(IgnoreParen);
1056 OCEE = dyn_cast<ObjCEncodeExpr>(IgnoreParen);
1060 if (ILE || CPLIE || SL || OCEE) {
1081 cast<ConstantArrayType>(
Init->getType()->getAsArrayTypeUnsafe())
1084 CurPtr, InitListElements,
"string.init.end");
1087 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1088 if (!ConstNum || !ConstNum->equalsInt(InitListElements)) {
1089 bool OK = TryMemsetInitialization();
1091 assert(OK &&
"couldn't memset character type?");
1098 InitListElements = InitExprs.size();
1102 QualType AllocType =
E->getAllocatedType();
1117 llvm::Instruction *DominatingIP =
1122 EndOfInit, ElementType, ElementAlign,
1125 .AddAuxAllocas(AllocaTracker.
Take());
1128 pushedCleanup =
true;
1133 for (
const Expr *IE : InitExprs) {
1159 while (
Init &&
Init->getType()->isConstantArrayType()) {
1160 auto *SubILE = dyn_cast<InitListExpr>(
Init);
1163 assert(SubILE->getNumInits() == 0 &&
"explicit inits in array filler?");
1164 Init = SubILE->getArrayFiller();
1173 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1174 if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
1178 assert(
Init &&
"have trailing elements to initialize but no initializer");
1190 if (TryMemsetInitialization())
1202 if (InitListElements)
1203 NumElements =
Builder.CreateSub(
1205 llvm::ConstantInt::get(NumElements->getType(), InitListElements));
1208 CCE->requiresZeroInitialization());
1214 if (isa<ImplicitValueInitExpr>(
Init)) {
1215 if (TryMemsetInitialization())
1226 assert(
getContext().hasSameUnqualifiedType(ElementType,
Init->getType()) &&
1227 "got wrong type of element to initialize");
1230 if (
auto *ILE = dyn_cast<InitListExpr>(
Init))
1231 if (ILE->
getNumInits() == 0 && TryMemsetInitialization())
1236 if (
auto *ILE = dyn_cast<InitListExpr>(
Init)) {
1239 if (RType->getOriginalDecl()->isStruct()) {
1241 unsigned NumElements = 0;
1242 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1243 NumElements = CXXRD->getNumBases();
1244 for (
auto *Field : RD->
fields())
1245 if (!Field->isUnnamedBitField())
1249 for (
unsigned i = 0, e = ILE->
getNumInits(); i != e; ++i)
1250 if (!isa<ImplicitValueInitExpr>(ILE->
getInit(i)))
1252 if (ILE->
getNumInits() == NumElements && TryMemsetInitialization())
1259 llvm::BasicBlock *EntryBB =
Builder.GetInsertBlock();
1272 EndPtr,
"array.isempty");
1273 Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
1280 llvm::PHINode *CurPtrPhi =
1292 llvm::Instruction *DominatingIP =
1309 llvm::Value *NextPtr =
Builder.CreateConstInBoundsGEP1_32(
1314 llvm::Value *IsEnd =
Builder.CreateICmpEQ(NextPtr, EndPtr,
"array.atend");
1315 Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
1316 CurPtrPhi->addIncoming(NextPtr,
Builder.GetInsertBlock());
1322 QualType ElementType, llvm::Type *ElementTy,
1323 Address NewPtr, llvm::Value *NumElements,
1324 llvm::Value *AllocSizeWithoutCookie) {
1328 AllocSizeWithoutCookie);
1329 else if (
const Expr *
Init =
E->getInitializer())
1340 llvm::CallBase *CallOrInvoke;
1345 Args, CalleeType,
false),
1353 llvm::Function *Fn = dyn_cast<llvm::Function>(CalleePtr);
1355 Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
1356 CallOrInvoke->addFnAttr(llvm::Attribute::Builtin);
1373 if (
auto *FD = dyn_cast<FunctionDecl>(
Decl))
1376 llvm_unreachable(
"predeclared global operator new/delete is missing");
1381struct UsualDeleteParams {
1383 bool DestroyingDelete =
false;
1390 UsualDeleteParams Params;
1409 Params.DestroyingDelete =
true;
1427 assert(AI == AE &&
"unexpected usual deallocation function parameter");
1435 template<
typename Traits>
1438 typedef typename Traits::ValueTy ValueTy;
1440 typedef typename Traits::RValueTy RValueTy;
1441 struct PlacementArg {
1446 unsigned NumPlacementArgs : 30;
1448 unsigned PassAlignmentToPlacementDelete : 1;
1450 RValueTy TypeIdentity;
1455 PlacementArg *getPlacementArgs() {
1456 return reinterpret_cast<PlacementArg *
>(
this + 1);
1460 static size_t getExtraSize(
size_t NumPlacementArgs) {
1461 return NumPlacementArgs *
sizeof(PlacementArg);
1464 CallDeleteDuringNew(
size_t NumPlacementArgs,
1466 RValueTy TypeIdentity, ValueTy Ptr, ValueTy AllocSize,
1469 : NumPlacementArgs(NumPlacementArgs),
1470 PassAlignmentToPlacementDelete(
1472 OperatorDelete(OperatorDelete), TypeIdentity(TypeIdentity), Ptr(Ptr),
1473 AllocSize(AllocSize), AllocAlign(AllocAlign) {}
1475 void setPlacementArg(
unsigned I, RValueTy Arg,
QualType Type) {
1476 assert(I < NumPlacementArgs &&
"index out of range");
1477 getPlacementArgs()[I] = {Arg,
Type};
1483 unsigned FirstNonTypeArg = 0;
1485 TypeAwareAllocationMode::No;
1486 if (OperatorDelete->isTypeAwareOperatorNewOrDelete()) {
1487 TypeAwareDeallocation = TypeAwareAllocationMode::Yes;
1488 QualType SpecializedTypeIdentity = FPT->getParamType(0);
1490 DeleteArgs.add(Traits::get(CGF, TypeIdentity), SpecializedTypeIdentity);
1494 DeleteArgs.add(Traits::get(CGF, Ptr), FPT->getParamType(FirstNonTypeArg));
1497 UsualDeleteParams Params;
1498 if (NumPlacementArgs) {
1503 Params.TypeAwareDelete = TypeAwareDeallocation;
1511 assert(!Params.DestroyingDelete &&
1512 "should not call destroying delete in a new-expression");
1516 DeleteArgs.add(Traits::get(CGF, AllocSize),
1524 DeleteArgs.add(
RValue::get(llvm::ConstantInt::get(
1529 for (
unsigned I = 0; I != NumPlacementArgs; ++I) {
1530 auto Arg = getPlacementArgs()[I];
1531 DeleteArgs.add(Traits::get(CGF, Arg.ArgValue), Arg.ArgType);
1544 llvm::Value *AllocSize,
CharUnits AllocAlign,
1546 unsigned NumNonPlacementArgs =
E->getNumImplicitArgs();
1551 struct DirectCleanupTraits {
1552 typedef llvm::Value *ValueTy;
1558 typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
1561 EHCleanup,
E->getNumPlacementArgs(),
E->getOperatorDelete(),
1563 E->implicitAllocationParameters(), AllocAlign);
1564 for (
unsigned I = 0, N =
E->getNumPlacementArgs(); I != N; ++I) {
1565 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1566 Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty);
1579 struct ConditionalCleanupTraits {
1583 return V.restore(CGF);
1586 typedef CallDeleteDuringNew<ConditionalCleanupTraits> ConditionalCleanup;
1588 ConditionalCleanup *Cleanup =
1590 EHCleanup,
E->getNumPlacementArgs(),
E->getOperatorDelete(),
1591 SavedTypeIdentity, SavedNewPtr, SavedAllocSize,
1592 E->implicitAllocationParameters(), AllocAlign);
1593 for (
unsigned I = 0, N =
E->getNumPlacementArgs(); I != N; ++I) {
1594 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1595 Cleanup->setPlacementArg(
1611 unsigned minElements = 0;
1612 unsigned IndexOfAlignArg = 1;
1613 if (
E->isArray() &&
E->hasInitializer()) {
1617 const Expr *IgnoreParen =
Init->IgnoreParenImpCasts();
1619 isa<StringLiteral>(IgnoreParen) || isa<ObjCEncodeExpr>(IgnoreParen)) {
1621 cast<ConstantArrayType>(
Init->getType()->getAsArrayTypeUnsafe())
1623 }
else if (ILE || CPLIE) {
1628 llvm::Value *numElements =
nullptr;
1629 llvm::Value *allocSizeWithoutCookie =
nullptr;
1630 llvm::Value *allocSize =
1632 allocSizeWithoutCookie);
1641 assert(
E->getNumPlacementArgs() == 1);
1642 const Expr *arg = *
E->placement_arguments().begin();
1655 if (
E->getOperatorDelete() &&
1656 !
E->getOperatorDelete()->isReservedGlobalPlacementOperator()) {
1658 allocatorArgs.
add(
RValue::get(allocation, *
this), arg->getType());
1665 unsigned ParamsToSkip = 0;
1671 allocatorArgs.
add(TypeIdentityArg, SpecializedTypeIdentity);
1680 if (allocSize != allocSizeWithoutCookie) {
1682 allocAlign = std::max(allocAlign, cookieAlign);
1689 AlignValT = allocatorType->
getParamType(IndexOfAlignArg);
1692 "wrong type for alignment parameter");
1696 assert(allocator->
isVariadic() &&
"can't pass alignment to allocator");
1704 EmitCallArgs(allocatorArgs, allocatorType,
E->placement_arguments(),
1712 if (
auto *newCall = dyn_cast<llvm::CallBase>(RV.
getScalarVal()))
1721 if (!
E->passAlignment() &&
1723 unsigned AllocatorAlign = llvm::bit_floor(std::min<uint64_t>(
1725 allocationAlign = std::max(
1726 allocationAlign,
getContext().toCharUnitsFromBits(AllocatorAlign));
1736 bool nullCheck =
E->shouldNullCheckAllocation() &&
1740 llvm::BasicBlock *nullCheckBB =
nullptr;
1741 llvm::BasicBlock *contBB =
nullptr;
1748 conditional.
begin(*
this);
1750 nullCheckBB =
Builder.GetInsertBlock();
1755 Builder.CreateCondBr(isNull, contBB, notNullBB);
1762 llvm::Instruction *cleanupDominator =
nullptr;
1763 if (
E->getOperatorDelete() &&
1764 !
E->getOperatorDelete()->isReservedGlobalPlacementOperator()) {
1766 allocAlign, allocatorArgs);
1768 cleanupDominator =
Builder.CreateUnreachable();
1771 assert((allocSize == allocSizeWithoutCookie) ==
1773 if (allocSize != allocSizeWithoutCookie) {
1774 assert(
E->isArray());
1797 SkippedChecks.
set(SanitizerKind::Null, nullCheck);
1799 E->getAllocatedTypeSourceInfo()->getTypeLoc().
getBeginLoc(),
1800 result, allocType, result.
getAlignment(), SkippedChecks,
1804 allocSizeWithoutCookie);
1809 if (operatorDeleteCleanup.
isValid()) {
1811 cleanupDominator->eraseFromParent();
1815 conditional.
end(*
this);
1817 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
1820 llvm::PHINode *PHI =
Builder.CreatePHI(resultPtr->getType(), 2);
1821 PHI->addIncoming(resultPtr, notNullBB);
1822 PHI->addIncoming(llvm::Constant::getNullValue(resultPtr->getType()),
1832 llvm::Value *DeletePtr,
QualType DeleteTy,
1833 llvm::Value *NumElements,
1835 assert((!NumElements && CookieSize.
isZero()) ||
1842 auto ParamTypeIt = DeleteFTy->param_type_begin();
1844 std::optional<llvm::AllocaInst *> TagAlloca;
1850 TagAllocation->setAlignment(Align.
getAsAlign());
1853 TagAlloca = TagAllocation;
1858 EmitTag(*ParamTypeIt++,
"typeaware.delete.tag");
1865 if (Params.DestroyingDelete)
1866 EmitTag(*ParamTypeIt++,
"destroying.delete.tag");
1870 QualType SizeType = *ParamTypeIt++;
1872 llvm::Value *Size = llvm::ConstantInt::get(
ConvertType(SizeType),
1877 Size =
Builder.CreateMul(Size, NumElements);
1880 if (!CookieSize.
isZero())
1889 QualType AlignValType = *ParamTypeIt++;
1893 llvm::Value *Align = llvm::ConstantInt::get(
ConvertType(AlignValType),
1898 assert(ParamTypeIt == DeleteFTy->param_type_end() &&
1899 "unknown parameter to usual delete function");
1906 if (TagAlloca && (*TagAlloca)->use_empty())
1907 (*TagAlloca)->eraseFromParent();
1916 CallObjectDelete(llvm::Value *Ptr,
1919 : Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
1929 llvm::Value *CompletePtr,
1932 OperatorDelete, ElementType);
1943 if (Dtor && Dtor->isVirtual())
1958 llvm::BasicBlock *UnconditionalDeleteBlock) {
1968 assert(!OperatorDelete->isDestroyingOperatorDelete());
1974 if (RD->hasDefinition() && !RD->hasTrivialDestructor()) {
1975 Dtor = RD->getDestructor();
1978 bool UseVirtualCall =
true;
1980 if (
auto *DevirtualizedDtor =
1981 dyn_cast_or_null<const CXXDestructorDecl>(
1984 UseVirtualCall =
false;
1990 Dtor = DevirtualizedDtor;
1997 UseVirtualCall =
true;
2000 if (UseVirtualCall) {
2012 CGF.
EHStack.pushCleanup<CallObjectDelete>(
2039 CGF.
EmitBlock(UnconditionalDeleteBlock);
2053 llvm::Value *NumElements;
2057 CallArrayDelete(llvm::Value *Ptr,
2059 llvm::Value *NumElements,
2062 : Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
2063 ElementType(ElementType), CookieSize(CookieSize) {}
2066 CGF.
EmitDeleteCall(OperatorDelete, Ptr, ElementType, NumElements,
2077 llvm::Value *numElements =
nullptr;
2078 llvm::Value *allocatedPtr =
nullptr;
2081 numElements, allocatedPtr, cookieSize);
2083 assert(allocatedPtr &&
"ReadArrayCookie didn't set allocated pointer");
2086 const FunctionDecl *operatorDelete =
E->getOperatorDelete();
2088 allocatedPtr, operatorDelete,
2089 numElements, elementType,
2094 assert(numElements &&
"no element count for a type with a destructor!");
2102 deletedPtr.
getElementType(), arrayBegin, numElements,
"delete.end");
2118 const Expr *Arg =
E->getArgument();
2137 QualType DeleteTy =
E->getDestroyedType();
2141 if (
E->getOperatorDelete()->isDestroyingOperatorDelete()) {
2151 if (
E->isArrayForm()) {
2161 llvm::Type *StdTypeInfoPtrTy,
2162 bool HasNullCheck) {
2173 ThisPtr, SrcRecordTy);
2180 llvm::BasicBlock *BadTypeidBlock =
2205 auto MaybeASCast = [=](
auto &&
TypeInfo) {
2211 if (
E->isTypeOperand()) {
2223 if (
E->isPotentiallyEvaluated() && !
E->isMostDerived(
getContext()))
2235 return llvm::Constant::getNullValue(DestLTy);
2242 CGF.
Builder.ClearInsertionPoint();
2243 return llvm::PoisonValue::get(DestLTy);
2259 if (IsDynamicCastToVoid) {
2266 SrcRecordTy = SrcTy;
2280 if (!
Builder.GetInsertBlock())
2286 assert(SrcRecordTy->
isRecordType() &&
"source type must be a record type!");
2290 bool IsExact = !IsDynamicCastToVoid &&
2296 std::optional<CGCXXABI::ExactDynamicCastInfo> ExactCastInfo;
2300 if (!ExactCastInfo) {
2302 if (!
Builder.GetInsertBlock())
2311 bool ShouldNullCheckSrcValue =
2315 llvm::BasicBlock *CastNull =
nullptr;
2316 llvm::BasicBlock *CastNotNull =
nullptr;
2319 if (ShouldNullCheckSrcValue) {
2329 if (IsDynamicCastToVoid) {
2331 }
else if (IsExact) {
2335 *
this, ThisAddr, SrcRecordTy, DestTy, DestRecordTy, *ExactCastInfo,
2339 "destination type must be a record type!");
2341 DestTy, DestRecordTy, CastEnd);
2343 CastNotNull =
Builder.GetInsertBlock();
2345 llvm::Value *NullValue =
nullptr;
2346 if (ShouldNullCheckSrcValue) {
2351 CastNull =
Builder.GetInsertBlock();
2360 PHI->addIncoming(
Value, CastNotNull);
2361 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 * EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, llvm::Type *StdTypeInfoPtrTy, bool HasNullCheck)
static llvm::Value * EmitDynamicCastToNull(CodeGenFunction &CGF, QualType DestTy)
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 ...
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 bool EmitObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, llvm::BasicBlock *UnconditionalDeleteBlock)
Emit the code for deleting a single object.
static UsualDeleteParams getUsualDeleteParams(const FunctionDecl *FD)
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 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)
llvm::MachO::Target Target
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,...
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
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.
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.
CanQualType getCanonicalTagType(const TagDecl *TD) const
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.
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
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....
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)".
QualType getAllocatedType() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
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]).
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...
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 ...
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
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::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::LoadInst * CreateFlagLoad(llvm::Value *Addr, const llvm::Twine &Name="")
Emit a load from an i1 flag variable.
Address CreateLaunderInvariantGroup(Address Addr)
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
llvm::ConstantInt * getSize(CharUnits N)
Address CreateConstInBoundsGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = T* ... produce name = getelementptr inbounds addr, i64 index where i64 is actually the t...
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual RValue EmitCUDAKernelCallExpr(CodeGenFunction &CGF, const CUDAKernelCallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke=nullptr)
virtual bool shouldEmitExactDynamicCast(QualType DestRecordTy)=0
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 std::optional< ExactDynamicCastInfo > getExactDynamicCastInfo(QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy)=0
virtual std::pair< llvm::Value *, const CXXRecordDecl * > LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD)=0
Load a vtable from This, an object of polymorphic type RD, or from one of its virtual bases if it doe...
virtual Address adjustThisArgumentForVirtualFunctionCall(CodeGenFunction &CGF, GlobalDecl GD, Address This, bool VirtualCall)
Perform ABI-specific "this" argument adjustment required prior to a call of a virtual function.
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 CGCallee EmitLoadOfMemberFunctionPointer(CodeGenFunction &CGF, const Expr *E, Address This, llvm::Value *&ThisPtrForCall, llvm::Value *MemPtr, const MemberPointerType *MPT)
Load a member function from an object and a member function pointer.
virtual llvm::Value * EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E, llvm::CallBase **CallOrInvoke)=0
Emit the ABI-specific virtual destructor call.
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
virtual llvm::Value * emitDynamicCastToVoid(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy)=0
virtual llvm::Value * emitDynamicCastCall(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastEnd)=0
virtual Address InitializeArrayCookie(CodeGenFunction &CGF, Address NewPtr, llvm::Value *NumElements, const CXXNewExpr *expr, QualType ElementType)
Initialize the array cookie for the given allocation.
virtual bool shouldDynamicCastCallBeNullChecked(bool SrcIsPtr, QualType SrcRecordTy)=0
virtual llvm::Value * emitExactDynamicCast(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, const ExactDynamicCastInfo &CastInfo, llvm::BasicBlock *CastSuccess, llvm::BasicBlock *CastFail)=0
Emit a dynamic_cast from SrcRecordTy to DestRecordTy.
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())
void addHeapAllocSiteMetadata(llvm::CallBase *CallSite, QualType AllocatedTy, SourceLocation Loc)
Add heapallocsite metadata for MSAllocator calls.
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)
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_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)
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)
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)
@ ForceRightToLeft
! Language semantics require right-to-left evaluation.
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,...
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
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)
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
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)
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)
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)
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
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)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Value * EmitCXXTypeidExpr(const CXXTypeidExpr *E)
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
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 * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for 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.
llvm::Constant * getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the constructor/destructor of the given type.
const LangOptions & getLangOpts() const
CGCUDARuntime & getCUDARuntime()
Return a reference to the configured CUDA runtime.
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
CGCXXABI & getCXXABI() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
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.
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
CanQualType DeriveThisType(const CXXRecordDecl *RD, const CXXMethodDecl *MD)
Derives the 'this' type for codegen purposes, i.e.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeCXXMethodCall(const CallArgList &args, const FunctionProtoType *type, RequiredArgs required, unsigned numPrefixArgs)
Arrange a call to a C++ method, passing the given arguments.
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.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
const CGFunctionInfo & arrangeCXXStructorDeclaration(GlobalDecl GD)
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
Information for lazily generating a cleanup.
A saved depth on the scope stack.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
T * pushCleanupWithExtra(CleanupKind Kind, size_t N, As... A)
Push a cleanup with non-constant storage requirements on the stack.
iterator find(stable_iterator save) const
Turn a stable reference to a scope depth into a unstable pointer to the EH stack.
AlignmentSource getAlignmentSource() const
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.
Decl - This represents one declaration (or definition), e.g.
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...
bool isVariadic() const
Whether this function is variadic.
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
bool isTypeAwareOperatorNewOrDelete() const
Determine whether this is a type aware operator new or delete.
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.
param_type_iterator param_type_begin() const
unsigned getNumParams() const
QualType getParamType(unsigned i) const
param_type_iterator param_type_end() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
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<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
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
RecordDecl * getDefinitionOrSelf() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isVoidPointerType() const
CXXRecordDecl * castAsCXXRecordDecl() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
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
@ 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
Matches all kinds of arrays.
The JSON file list parser is used to communicate input to InstallAPI.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
AlignedAllocationMode alignedAllocationModeFromBool(bool IsAligned)
bool isAlignedAllocation(AlignedAllocationMode Mode)
@ Dtor_Complete
Complete object dtor.
bool isTypeAwareAllocation(TypeAwareAllocationMode Mode)
LangAS
Defines the address space values used by the address space qualifier of QualType.
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
llvm::SmallVector< llvm::AllocaInst * > Take()
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.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.