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);
104 llvm::CallBase **CallOrInvoke) {
109 "Pointer/Object mixup");
113 if (SrcAS != DstAS) {
115 llvm::Type *NewType =
CGM.getTypes().ConvertType(DstTy);
121 ImplicitParamTy, CE, Args,
nullptr);
122 return EmitCall(
CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee,
143 BaseQuals = PTy->getPointeeType().getQualifiers();
182 T = PTy->getPointeeType();
183 return T->castAsCXXRecordDecl();
190 llvm::CallBase **CallOrInvoke) {
213 HasQualifier, Qualifier, IsArrow,
220 const Expr *
Base, llvm::CallBase **CallOrInvoke) {
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) {
313 if (TrivialAssignment) {
320 ? TrivialAssignmentRHS
327 "unknown trivial member function");
332 DevirtualizedMethod ? DevirtualizedMethod : MD;
334 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl))
335 FInfo = &
CGM.getTypes().arrangeCXXStructorDeclaration(
338 FInfo = &
CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl);
340 llvm::FunctionType *Ty =
CGM.getTypes().GetFunctionType(*FInfo);
351 if (
const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
352 auto *IOA = CMCE->getImplicitObjectArgument();
354 if (IsImplicitObjectCXXThis)
355 SkippedChecks.
set(SanitizerKind::Alignment,
true);
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) {
379 CGM.getCXXABI().EmitVirtualDestructorCall(
385 if (
getLangOpts().AppleKext && Dtor->isVirtual() && HasQualifier)
387 else if (!DevirtualizedMethod)
395 IsArrow ?
Base->getType()->getPointeeType() :
Base->getType();
407 if (UseVirtualCall) {
410 if (
SanOpts.has(SanitizerKind::CFINVCall) &&
414 std::tie(VTable, RD) =
CGM.getCXXABI().LoadVTablePtr(
421 else if (!DevirtualizedMethod)
433 CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
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;
473 CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*
this, BO,
This,
474 ThisPtrForCall, MemFnPtr, MPT);
487 return EmitCall(
CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required,
497 "Trying to emit a member call expr on a static method!");
500 false, E->
getArg(0), CallOrInvoke);
505 llvm::CallBase **CallOrInvoke) {
509 return CGM.getCUDARuntime().EmitCUDADeviceKernelCallExpr(
511 return CGM.getCUDARuntime().EmitCUDAKernelCallExpr(*
this, E,
ReturnValue,
534 std::vector<CharUnits> VBPtrOffsets =
536 for (
CharUnits VBPtrOffset : VBPtrOffsets) {
538 if (VBPtrOffset >= NVSize)
540 std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val();
541 CharUnits LastStoreOffset = LastStore.first;
542 CharUnits LastStoreSize = LastStore.second;
544 CharUnits SplitBeforeOffset = LastStoreOffset;
545 CharUnits SplitBeforeSize = VBPtrOffset - SplitBeforeOffset;
546 assert(!SplitBeforeSize.
isNegative() &&
"negative store size!");
547 if (!SplitBeforeSize.
isZero())
548 Stores.emplace_back(SplitBeforeOffset, SplitBeforeSize);
550 CharUnits SplitAfterOffset = VBPtrOffset + VBPtrWidth;
551 CharUnits SplitAfterSize = LastStoreSize - SplitAfterOffset;
552 assert(!SplitAfterSize.
isNegative() &&
"negative store size!");
553 if (!SplitAfterSize.
isZero())
554 Stores.emplace_back(SplitAfterOffset, SplitAfterSize);
564 if (!NullConstantForBase->isNullValue()) {
565 llvm::GlobalVariable *NullVariable =
new llvm::GlobalVariable(
567 true, llvm::GlobalVariable::PrivateLinkage,
568 NullConstantForBase, Twine());
572 NullVariable->setAlignment(Align.
getAsAlign());
577 for (std::pair<CharUnits, CharUnits> Store : Stores) {
580 llvm::Value *StoreSizeVal = CGF.
CGM.
getSize(StoreSize);
591 for (std::pair<CharUnits, CharUnits> Store : Stores) {
594 llvm::Value *StoreSizeVal = CGF.
CGM.
getSize(StoreSize);
597 CGF.
Builder.getInt8(0), StoreSizeVal);
605 assert(!Dest.
isIgnored() &&
"Must have a destination!");
651 bool ForVirtualBase =
false;
666 ForVirtualBase =
true;
681 Exp = E->getSubExpr();
683 "EmitSynthesizedCXXCopyCtor - unknown copy ctor expr");
696 &&
"EmitSynthesizedCXXCopyCtor - Copied-in Array");
715 unsigned minElements,
716 llvm::Value *&numElements,
717 llvm::Value *&sizeWithoutCookie) {
724 return sizeWithoutCookie;
728 unsigned sizeWidth = CGF.
SizeTy->getBitWidth();
731 llvm::APInt cookieSize(sizeWidth,
750 = (*e->
getArraySize())->getType()->isSignedIntegerOrEnumerationType();
751 llvm::IntegerType *numElementsType
753 unsigned numElementsWidth = numElementsType->getBitWidth();
756 llvm::APInt arraySizeMultiplier(sizeWidth, 1);
759 type = CAT->getElementType();
760 arraySizeMultiplier *= CAT->getSize();
764 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.
getQuantity());
765 typeSizeMultiplier *= arraySizeMultiplier;
772 if (llvm::ConstantInt *numElementsC =
773 dyn_cast<llvm::ConstantInt>(numElements)) {
774 const llvm::APInt &count = numElementsC->getValue();
776 bool hasAnyOverflow =
false;
779 if (isSigned && count.isNegative())
780 hasAnyOverflow =
true;
785 else if (numElementsWidth > sizeWidth &&
786 numElementsWidth - sizeWidth > count.countl_zero())
787 hasAnyOverflow =
true;
790 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
794 if (adjustedCount.ult(minElements))
795 hasAnyOverflow =
true;
800 numElements = llvm::ConstantInt::get(CGF.
SizeTy,
801 adjustedCount * arraySizeMultiplier);
805 llvm::APInt allocationSize
806 = adjustedCount.umul_ov(typeSizeMultiplier, overflow);
807 hasAnyOverflow |= overflow;
810 if (cookieSize != 0) {
813 sizeWithoutCookie = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
815 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
816 hasAnyOverflow |= overflow;
820 if (hasAnyOverflow) {
821 size = llvm::Constant::getAllOnesValue(CGF.
SizeTy);
823 size = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
841 llvm::Value *hasOverflow =
nullptr;
846 if (numElementsWidth > sizeWidth) {
847 llvm::APInt threshold =
848 llvm::APInt::getOneBitSet(numElementsWidth, sizeWidth);
850 llvm::Value *thresholdV
851 = llvm::ConstantInt::get(numElementsType, threshold);
853 hasOverflow = CGF.
Builder.CreateICmpUGE(numElements, thresholdV);
854 numElements = CGF.
Builder.CreateTrunc(numElements, CGF.
SizeTy);
857 }
else if (isSigned) {
858 if (numElementsWidth < sizeWidth)
859 numElements = CGF.
Builder.CreateSExt(numElements, CGF.
SizeTy);
866 if (typeSizeMultiplier == 1)
867 hasOverflow = CGF.
Builder.CreateICmpSLT(numElements,
868 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
871 }
else if (numElementsWidth < sizeWidth) {
872 numElements = CGF.
Builder.CreateZExt(numElements, CGF.
SizeTy);
875 assert(numElements->getType() == CGF.
SizeTy);
880 hasOverflow = CGF.
Builder.CreateICmpULT(numElements,
881 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
882 }
else if (numElementsWidth > sizeWidth) {
886 hasOverflow = CGF.
Builder.CreateOr(hasOverflow,
887 CGF.
Builder.CreateICmpULT(numElements,
888 llvm::ConstantInt::get(CGF.
SizeTy, minElements)));
901 if (typeSizeMultiplier != 1) {
902 llvm::Function *umul_with_overflow
906 llvm::ConstantInt::get(CGF.
SizeTy, typeSizeMultiplier);
907 llvm::Value *result =
908 CGF.
Builder.CreateCall(umul_with_overflow, {size, tsmV});
910 llvm::Value *overflowed = CGF.
Builder.CreateExtractValue(result, 1);
912 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
914 hasOverflow = overflowed;
916 size = CGF.
Builder.CreateExtractValue(result, 0);
919 if (arraySizeMultiplier != 1) {
922 if (typeSize.
isOne()) {
923 assert(arraySizeMultiplier == typeSizeMultiplier);
929 llvm::ConstantInt::get(CGF.
SizeTy, arraySizeMultiplier);
930 numElements = CGF.
Builder.CreateMul(numElements, asmV);
935 assert(arraySizeMultiplier == 1);
939 if (cookieSize != 0) {
940 sizeWithoutCookie = size;
942 llvm::Function *uadd_with_overflow
945 llvm::Value *cookieSizeV = llvm::ConstantInt::get(CGF.
SizeTy, cookieSize);
946 llvm::Value *result =
947 CGF.
Builder.CreateCall(uadd_with_overflow, {size, cookieSizeV});
949 llvm::Value *overflowed = CGF.
Builder.CreateExtractValue(result, 1);
951 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
953 hasOverflow = overflowed;
955 size = CGF.
Builder.CreateExtractValue(result, 0);
962 size = CGF.
Builder.CreateSelect(hasOverflow,
963 llvm::Constant::getAllOnesValue(CGF.
SizeTy),
968 sizeWithoutCookie = size;
970 assert(sizeWithoutCookie &&
"didn't set sizeWithoutCookie?");
1000 llvm_unreachable(
"bad evaluation kind");
1005 Address BeginPtr, llvm::Value *NumElements,
1006 llvm::Value *AllocSizeWithoutCookie) {
1014 unsigned InitListElements = 0;
1020 bool pushedCleanup =
false;
1027 auto TryMemsetInitialization = [&]() ->
bool {
1030 if (!
CGM.getTypes().isZeroInitializable(ElementType))
1037 auto *RemainingSize = AllocSizeWithoutCookie;
1038 if (InitListElements) {
1040 auto *InitializedSize = llvm::ConstantInt::get(
1041 RemainingSize->getType(),
1042 getContext().getTypeSizeInChars(ElementType).getQuantity() *
1044 RemainingSize =
Builder.CreateSub(RemainingSize, InitializedSize);
1048 Builder.CreateMemSet(CurPtr,
Builder.getInt8(0), RemainingSize,
false);
1056 const Expr *IgnoreParen =
nullptr;
1058 IgnoreParen =
Init->IgnoreParenImpCasts();
1059 CPLIE = dyn_cast<CXXParenListInitExpr>(IgnoreParen);
1060 SL = dyn_cast<StringLiteral>(IgnoreParen);
1061 OCEE = dyn_cast<ObjCEncodeExpr>(IgnoreParen);
1065 if (ILE || CPLIE || SL || OCEE) {
1088 CurPtr =
Builder.CreateConstInBoundsGEP(
1089 CurPtr, InitListElements,
"string.init.end");
1092 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1093 if (!ConstNum || !ConstNum->equalsInt(InitListElements)) {
1094 bool OK = TryMemsetInitialization();
1096 assert(OK &&
"couldn't memset character type?");
1103 InitListElements = InitExprs.size();
1122 llvm::Instruction *DominatingIP =
1127 EndOfInit, ElementType, ElementAlign,
1130 .AddAuxAllocas(AllocaTracker.Take());
1132 {
EHStack.stable_begin(), DominatingIP});
1133 pushedCleanup =
true;
1138 for (
const Expr *IE : InitExprs) {
1164 while (
Init &&
Init->getType()->isConstantArrayType()) {
1165 auto *SubILE = dyn_cast<InitListExpr>(
Init);
1168 assert(SubILE->getNumInits() == 0 &&
"explicit inits in array filler?");
1169 Init = SubILE->getArrayFiller();
1178 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1179 if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
1183 assert(
Init &&
"have trailing elements to initialize but no initializer");
1195 if (TryMemsetInitialization())
1207 if (InitListElements)
1208 NumElements =
Builder.CreateSub(
1210 llvm::ConstantInt::get(NumElements->getType(), InitListElements));
1213 CCE->requiresZeroInitialization());
1220 if (TryMemsetInitialization())
1231 assert(
getContext().hasSameUnqualifiedType(ElementType,
Init->getType()) &&
1232 "got wrong type of element to initialize");
1235 if (
auto *ILE = dyn_cast<InitListExpr>(
Init))
1236 if (ILE->
getNumInits() == 0 && TryMemsetInitialization())
1241 if (
auto *ILE = dyn_cast<InitListExpr>(
Init)) {
1242 if (
const RecordType *RType =
1244 if (RType->getDecl()->isStruct()) {
1246 unsigned NumElements = 0;
1247 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
1248 NumElements = CXXRD->getNumBases();
1249 for (
auto *Field : RD->
fields())
1250 if (!Field->isUnnamedBitField())
1254 for (
unsigned i = 0, e = ILE->
getNumInits(); i != e; ++i)
1257 if (ILE->
getNumInits() == NumElements && TryMemsetInitialization())
1264 llvm::BasicBlock *EntryBB =
Builder.GetInsertBlock();
1269 llvm::Value *EndPtr =
Builder.CreateInBoundsGEP(
1277 EndPtr,
"array.isempty");
1278 Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
1285 llvm::PHINode *CurPtrPhi =
1297 llvm::Instruction *DominatingIP =
1303 {
EHStack.stable_begin(), DominatingIP});
1314 llvm::Value *NextPtr =
Builder.CreateConstInBoundsGEP1_32(
1319 llvm::Value *IsEnd =
Builder.CreateICmpEQ(NextPtr, EndPtr,
"array.atend");
1320 Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
1321 CurPtrPhi->addIncoming(NextPtr,
Builder.GetInsertBlock());
1327 QualType ElementType, llvm::Type *ElementTy,
1328 Address NewPtr, llvm::Value *NumElements,
1329 llvm::Value *AllocSizeWithoutCookie) {
1333 AllocSizeWithoutCookie);
1345 llvm::CallBase *CallOrInvoke;
1350 Args, CalleeType,
false),
1358 llvm::Function *Fn = dyn_cast<llvm::Function>(CalleePtr);
1360 Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
1361 CallOrInvoke->addFnAttr(llvm::Attribute::Builtin);
1378 if (
auto *FD = dyn_cast<FunctionDecl>(
Decl))
1381 if (
auto *CB = dyn_cast_if_present<llvm::CallBase>(RV.
getScalarVal())) {
1382 if (
SanOpts.has(SanitizerKind::AllocToken)) {
1389 llvm_unreachable(
"predeclared global operator new/delete is missing");
1396 template<
typename Traits>
1397 class CallDeleteDuringNew final :
public EHScopeStack::Cleanup {
1399 typedef typename Traits::ValueTy ValueTy;
1401 typedef typename Traits::RValueTy RValueTy;
1402 struct PlacementArg {
1407 unsigned NumPlacementArgs : 30;
1409 unsigned PassAlignmentToPlacementDelete : 1;
1411 RValueTy TypeIdentity;
1416 PlacementArg *getPlacementArgs() {
1417 return reinterpret_cast<PlacementArg *
>(
this + 1);
1421 static size_t getExtraSize(
size_t NumPlacementArgs) {
1422 return NumPlacementArgs *
sizeof(PlacementArg);
1425 CallDeleteDuringNew(
size_t NumPlacementArgs,
1426 const FunctionDecl *OperatorDelete,
1427 RValueTy TypeIdentity, ValueTy Ptr, ValueTy AllocSize,
1428 const ImplicitAllocationParameters &IAP,
1429 CharUnits AllocAlign)
1430 : NumPlacementArgs(NumPlacementArgs),
1431 PassAlignmentToPlacementDelete(
1433 OperatorDelete(OperatorDelete), TypeIdentity(TypeIdentity), Ptr(Ptr),
1434 AllocSize(AllocSize), AllocAlign(AllocAlign) {}
1436 void setPlacementArg(
unsigned I, RValueTy Arg, QualType
Type) {
1437 assert(I < NumPlacementArgs &&
"index out of range");
1438 getPlacementArgs()[I] = {Arg,
Type};
1441 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1442 const auto *FPT = OperatorDelete->getType()->castAs<FunctionProtoType>();
1443 CallArgList DeleteArgs;
1444 unsigned FirstNonTypeArg = 0;
1446 TypeAwareAllocationMode::No;
1447 if (OperatorDelete->isTypeAwareOperatorNewOrDelete()) {
1448 TypeAwareDeallocation = TypeAwareAllocationMode::Yes;
1449 QualType SpecializedTypeIdentity = FPT->getParamType(0);
1451 DeleteArgs.add(Traits::get(CGF, TypeIdentity), SpecializedTypeIdentity);
1455 DeleteArgs.add(Traits::get(CGF, Ptr), FPT->getParamType(FirstNonTypeArg));
1458 UsualDeleteParams Params;
1459 if (NumPlacementArgs) {
1469 Params = OperatorDelete->getUsualDeleteParams();
1473 "should not call destroying delete in a new-expression");
1477 DeleteArgs.add(Traits::get(CGF, AllocSize),
1485 DeleteArgs.add(
RValue::get(llvm::ConstantInt::get(
1490 for (
unsigned I = 0; I != NumPlacementArgs; ++I) {
1491 auto Arg = getPlacementArgs()[I];
1492 DeleteArgs.add(Traits::get(CGF, Arg.ArgValue), Arg.ArgType);
1505 llvm::Value *AllocSize,
CharUnits AllocAlign,
1512 struct DirectCleanupTraits {
1513 typedef llvm::Value *ValueTy;
1519 typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
1526 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1527 Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty);
1540 struct ConditionalCleanupTraits {
1544 return V.restore(CGF);
1547 typedef CallDeleteDuringNew<ConditionalCleanupTraits> ConditionalCleanup;
1549 ConditionalCleanup *Cleanup =
1552 SavedTypeIdentity, SavedNewPtr, SavedAllocSize,
1555 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1556 Cleanup->setPlacementArg(
1572 unsigned minElements = 0;
1573 unsigned IndexOfAlignArg = 1;
1578 const Expr *IgnoreParen =
Init->IgnoreParenImpCasts();
1584 }
else if (ILE || CPLIE) {
1589 llvm::Value *numElements =
nullptr;
1590 llvm::Value *allocSizeWithoutCookie =
nullptr;
1591 llvm::Value *allocSize =
1593 allocSizeWithoutCookie);
1601 if (allocator->isReservedGlobalPlacementOperator()) {
1619 allocatorArgs.
add(
RValue::get(allocation, *
this), arg->getType());
1626 unsigned ParamsToSkip = 0;
1632 allocatorArgs.
add(TypeIdentityArg, SpecializedTypeIdentity);
1641 if (allocSize != allocSizeWithoutCookie) {
1643 allocAlign = std::max(allocAlign, cookieAlign);
1650 AlignValT = allocatorType->
getParamType(IndexOfAlignArg);
1653 "wrong type for alignment parameter");
1657 assert(allocator->isVariadic() &&
"can't pass alignment to allocator");
1671 if (
auto *newCall = dyn_cast<llvm::CallBase>(RV.
getScalarVal())) {
1674 CGDI->addHeapAllocSiteMetadata(newCall, allocType, E->
getExprLoc());
1676 if (
SanOpts.has(SanitizerKind::AllocToken)) {
1688 allocator->isReplaceableGlobalAllocationFunction()) {
1689 unsigned AllocatorAlign = llvm::bit_floor(std::min<uint64_t>(
1691 allocationAlign = std::max(
1692 allocationAlign,
getContext().toCharUnitsFromBits(AllocatorAlign));
1706 llvm::BasicBlock *nullCheckBB =
nullptr;
1707 llvm::BasicBlock *contBB =
nullptr;
1714 conditional.
begin(*
this);
1716 nullCheckBB =
Builder.GetInsertBlock();
1720 llvm::Value *isNull =
Builder.CreateIsNull(allocation,
"new.isnull");
1721 Builder.CreateCondBr(isNull, contBB, notNullBB);
1728 llvm::Instruction *cleanupDominator =
nullptr;
1732 allocAlign, allocatorArgs);
1733 operatorDeleteCleanup =
EHStack.stable_begin();
1734 cleanupDominator =
Builder.CreateUnreachable();
1737 assert((allocSize == allocSizeWithoutCookie) ==
1739 if (allocSize != allocSizeWithoutCookie) {
1741 allocation =
CGM.getCXXABI().InitializeArrayCookie(*
this, allocation,
1753 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1754 allocator->isReservedGlobalPlacementOperator())
1755 result =
Builder.CreateLaunderInvariantGroup(result);
1763 SkippedChecks.
set(SanitizerKind::Null, nullCheck);
1766 result, allocType, result.
getAlignment(), SkippedChecks,
1770 allocSizeWithoutCookie);
1775 if (operatorDeleteCleanup.
isValid()) {
1777 cleanupDominator->eraseFromParent();
1781 conditional.
end(*
this);
1783 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
1786 llvm::PHINode *PHI =
Builder.CreatePHI(resultPtr->getType(), 2);
1787 PHI->addIncoming(resultPtr, notNullBB);
1788 PHI->addIncoming(llvm::Constant::getNullValue(resultPtr->getType()),
1798 llvm::Value *DeletePtr,
QualType DeleteTy,
1799 llvm::Value *NumElements,
1801 assert((!NumElements && CookieSize.
isZero()) ||
1808 auto ParamTypeIt = DeleteFTy->param_type_begin();
1810 std::optional<llvm::AllocaInst *> TagAlloca;
1811 auto EmitTag = [&](
QualType TagType,
const char *TagName) {
1814 CharUnits Align =
CGM.getNaturalTypeAlignment(TagType);
1816 TagAllocation->setAlignment(Align.
getAsAlign());
1819 TagAlloca = TagAllocation;
1824 EmitTag(*ParamTypeIt++,
"typeaware.delete.tag");
1832 EmitTag(*ParamTypeIt++,
"destroying.delete.tag");
1836 QualType SizeType = *ParamTypeIt++;
1838 llvm::Value *Size = llvm::ConstantInt::get(
ConvertType(SizeType),
1843 Size =
Builder.CreateMul(Size, NumElements);
1846 if (!CookieSize.
isZero())
1855 QualType AlignValType = *ParamTypeIt++;
1859 llvm::Value *Align = llvm::ConstantInt::get(
ConvertType(AlignValType),
1864 assert(ParamTypeIt == DeleteFTy->param_type_end() &&
1865 "unknown parameter to usual delete function");
1872 if (TagAlloca && (*TagAlloca)->use_empty())
1873 (*TagAlloca)->eraseFromParent();
1877 struct CallObjectDelete final : EHScopeStack::Cleanup {
1882 CallObjectDelete(llvm::Value *Ptr,
1885 : Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
1895 llvm::Value *CompletePtr,
1898 OperatorDelete, ElementType);
1909 if (Dtor && Dtor->isVirtual())
1922 llvm::BasicBlock *UnconditionalDeleteBlock) {
1932 assert(!OperatorDelete->isDestroyingOperatorDelete());
1938 if (RD->hasDefinition() && !RD->hasTrivialDestructor()) {
1939 Dtor = RD->getDestructor();
1942 bool UseVirtualCall =
true;
1944 if (
auto *DevirtualizedDtor =
1945 dyn_cast_or_null<const CXXDestructorDecl>(
1948 UseVirtualCall =
false;
1954 Dtor = DevirtualizedDtor;
1961 UseVirtualCall =
true;
1964 if (UseVirtualCall) {
1976 CGF.
EHStack.pushCleanup<CallObjectDelete>(
2003 CGF.
EmitBlock(UnconditionalDeleteBlock);
2014 struct CallArrayDelete final : EHScopeStack::Cleanup {
2016 const FunctionDecl *OperatorDelete;
2017 llvm::Value *NumElements;
2018 QualType ElementType;
2019 CharUnits CookieSize;
2021 CallArrayDelete(llvm::Value *Ptr,
2022 const FunctionDecl *OperatorDelete,
2023 llvm::Value *NumElements,
2024 QualType ElementType,
2025 CharUnits CookieSize)
2026 : Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
2027 ElementType(ElementType), CookieSize(CookieSize) {}
2029 void Emit(CodeGenFunction &CGF, Flags flags)
override {
2030 CGF.
EmitDeleteCall(OperatorDelete, Ptr, ElementType, NumElements,
2041 llvm::Value *numElements =
nullptr;
2042 llvm::Value *allocatedPtr =
nullptr;
2045 numElements, allocatedPtr, cookieSize);
2047 assert(allocatedPtr &&
"ReadArrayCookie didn't set allocated pointer");
2052 allocatedPtr, operatorDelete,
2053 numElements, elementType,
2058 assert(numElements &&
"no element count for a type with a destructor!");
2066 deletedPtr.
getElementType(), arrayBegin, numElements,
"delete.end");
2116 CGM.getContext().getTargetInfo().emitVectorDeletingDtors(
2117 CGM.getContext().getLangOpts())) {
2119 auto *Dtor = RD->getDestructor();
2120 if (Dtor && Dtor->isVirtual()) {
2121 llvm::Value *NumElements =
nullptr;
2122 llvm::Value *AllocatedPtr =
nullptr;
2128 CGM.getCXXABI().ReadArrayCookie(*
this, Ptr, E, DeleteTy, NumElements,
2129 AllocatedPtr, CookieSize);
2132 llvm::Value *IsEmpty =
Builder.CreateICmpEQ(
2133 NumElements, llvm::ConstantInt::get(CondTy, 0));
2134 Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
2139 EmitDeleteCall(OperatorDelete, AllocatedPtr, DeleteTy, NumElements,
2161 llvm::Type *StdTypeInfoPtrTy,
2162 bool HasNullCheck) {
2173 ThisPtr, SrcRecordTy);
2180 llvm::BasicBlock *BadTypeidBlock =
2203 LangAS GlobAS =
CGM.GetGlobalVarAddressSpace(
nullptr);
2205 auto MaybeASCast = [=](
auto &&
TypeInfo) {
2228 return MaybeASCast(
CGM.GetAddrOfRTTIDescriptor(OperandTy));
2235 return llvm::Constant::getNullValue(DestLTy);
2242 CGF.
Builder.ClearInsertionPoint();
2243 return llvm::PoisonValue::get(DestLTy);
2248 CGM.EmitExplicitCastExprType(DCE,
this);
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 &&
2291 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2293 CGM.getCXXABI().shouldEmitExactDynamicCast(DestRecordTy);
2295 std::optional<CGCXXABI::ExactDynamicCastInfo> ExactCastInfo;
2297 ExactCastInfo =
CGM.getCXXABI().getExactDynamicCastInfo(SrcRecordTy, DestTy,
2299 if (!ExactCastInfo) {
2301 if (!
Builder.GetInsertBlock())
2310 bool ShouldNullCheckSrcValue =
2311 IsExact ||
CGM.getCXXABI().shouldDynamicCastCallBeNullChecked(
2314 llvm::BasicBlock *CastNull =
nullptr;
2315 llvm::BasicBlock *CastNotNull =
nullptr;
2318 if (ShouldNullCheckSrcValue) {
2328 if (IsDynamicCastToVoid) {
2329 Value =
CGM.getCXXABI().emitDynamicCastToVoid(*
this, ThisAddr, SrcRecordTy);
2330 }
else if (IsExact) {
2333 Value =
CGM.getCXXABI().emitExactDynamicCast(
2334 *
this, ThisAddr, SrcRecordTy, DestTy, DestRecordTy, *ExactCastInfo,
2338 "destination type must be a record type!");
2339 Value =
CGM.getCXXABI().emitDynamicCastCall(*
this, ThisAddr, SrcRecordTy,
2340 DestTy, DestRecordTy, CastEnd);
2342 CastNotNull =
Builder.GetInsertBlock();
2344 llvm::Value *NullValue =
nullptr;
2345 if (ShouldNullCheckSrcValue) {
2350 CastNull =
Builder.GetInsertBlock();
2359 PHI->addIncoming(
Value, CastNotNull);
2360 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 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)
static QualType getPointeeType(const MemRegion *R)
a trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
DeclarationNameTable DeclarationNames
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a call to a CUDA kernel function.
Represents a call to a C++ constructor.
bool isElidable() const
Whether this construction is elidable.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
CXXConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
Represents a C++ constructor within a class.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
Represents a delete expression for memory deallocation and destructor calls, e.g.
FunctionDecl * getOperatorDelete() const
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ destructor within a class.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
bool isAlwaysNull() const
isAlwaysNull - Return whether the result of the dynamic_cast is proven to always be null.
Represents a call to a member function that may be written either with member call syntax (e....
SourceLocation getExprLoc() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
Qualifiers getMethodQualifiers() const
CXXMethodDecl * getDevirtualizedMethod(const Expr *Base, bool IsAppleKext)
If it's possible to devirtualize a call to this method, return the called function.
CXXMethodDecl * getCorrespondingMethodInClass(const CXXRecordDecl *RD, bool MayBeBase=false)
Find the method in RD that corresponds to this one.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
llvm::iterator_range< arg_iterator > placement_arguments()
QualType getAllocatedType() const
unsigned getNumImplicitArgs() const
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
ImplicitAllocationParameters implicitAllocationParameters() const
Provides the full set of information about expected implicit parameters in this call.
bool hasInitializer() const
Whether this new-expression has any initializer at all.
bool shouldNullCheckAllocation() const
True if the allocation result needs to be null-checked.
bool passAlignment() const
Indicates whether the required alignment should be implicitly passed to the allocation function.
FunctionDecl * getOperatorDelete() const
unsigned getNumPlacementArgs() const
TypeSourceInfo * getAllocatedTypeSourceInfo() const
FunctionDecl * getOperatorNew() const
Expr * getInitializer()
The initializer of this new-expression.
A call to an overloaded operator written using operator syntax.
Represents a list-initialization with parenthesis.
MutableArrayRef< Expr * > getInitExprs()
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool isDynamicClass() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
An expression "T()" which creates an rvalue of a non-class type T.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
bool isTypeOperand() const
QualType getTypeOperand(const ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
Expr * getExprOperand() const
bool isMostDerived(const ASTContext &Context) const
Best-effort check if the expression operand refers to a most derived object.
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr....
bool hasNullCheck() const
Whether this is of a form like "typeid(*ptr)" that can throw a std::bad_typeid if a pointer is a null...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
bool isOne() const
isOne - Test whether the quantity equals one.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
Address setKnownNonNull()
void setAlignment(CharUnits Value)
llvm::PointerType * getType() const
Return the type of the pointer value.
bool isSanitizerChecked() const
Address getAddress() const
IsZeroed_t isZeroed() const
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
A scoped helper to set the current debug location to the specified location or preferred location of ...
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual std::vector< CharUnits > getVBPtrOffsets(const CXXRecordDecl *RD)
Gets the offsets of all the virtual base pointers in a given class.
virtual void ReadArrayCookie(CodeGenFunction &CGF, Address Ptr, const CXXDeleteExpr *expr, QualType ElementType, llvm::Value *&NumElements, llvm::Value *&AllocPtr, CharUnits &CookieSize)
Reads the array cookie associated with the given pointer, if it has one.
virtual bool shouldTypeidBeNullChecked(QualType SrcRecordTy)=0
virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0
virtual const CXXRecordDecl * getThisArgumentTypeForMethod(GlobalDecl GD)
Get the type of the implicit "this" parameter used by a method.
virtual bool EmitBadCastCall(CodeGenFunction &CGF)=0
virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0
virtual CharUnits GetArrayCookieSize(const CXXNewExpr *expr)
Returns the extra size required in order to store the array cookie for the given new-expression.
virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0
All available information about a concrete callee.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
An abstract representation of regular/ObjC call/message targets.
An object to manage conditionally-evaluated expressions.
void begin(CodeGenFunction &CGF)
void end(CodeGenFunction &CGF)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, QualType elementType, CharUnits elementAlign, Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup)
emitArrayDestroy - Destroys all the elements of the given array, beginning from last to first.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest)
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
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)
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)
const TargetInfo & Target
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD, NestedNameSpecifier Qual, llvm::Type *Ty)
BuildAppleKextVirtualCall - This routine is to support gcc's kext ABI making indirect call to virtual...
RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
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)
llvm::Module & getModule() const
llvm::Constant * EmitNullConstantForBase(const CXXRecordDecl *Record)
Return a null constant appropriate for zero-initializing a base class with the given type.
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
CGCXXABI & getCXXABI() const
const CodeGenOptions & getCodeGenOpts() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
CanQualType DeriveThisType(const CXXRecordDecl *RD, const CXXMethodDecl *MD)
Derives the 'this' type for codegen purposes, i.e.
const CGFunctionInfo & arrangeFreeFunctionCall(const CallArgList &Args, const FunctionType *Ty, bool ChainCall)
Figure out the rules for calling a function with the given formal type using the given arguments.
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
A saved depth on the scope stack.
T * pushCleanupWithExtra(CleanupKind Kind, size_t N, As... A)
Push a cleanup with non-constant storage requirements on the stack.
LValue - This represents an lvalue references.
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
A class for recording the number of arguments that a function signature requires.
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Represents the canonical version of C arrays with a specified constant size.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
The name of a declaration.
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a function declaration or definition.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
QualType getReturnType() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isReplaceableGlobalAllocationFunction(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
UsualDeleteParams getUsualDeleteParams() const
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
bool isDefaulted() const
Whether this function is defaulted.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
Represents a prototype with parameter type info, e.g.
unsigned getNumParams() const
QualType getParamType(unsigned i) const
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
Represents an implicitly-generated value initialization of an object of a given type.
Describes an C or C++ initializer list.
bool isStringLiteralInit() const
Is this an initializer for an array of characters, initialized by a string literal or an @encode?
unsigned getNumInits() const
Expr * getArrayFiller()
If this initializer list initializes an array with more elements than there are initializers in the l...
const Expr * getInit(unsigned Init) const
ArrayRef< Expr * > inits()
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
NestedNameSpecifier getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
bool hasQualifier() const
Determines whether this member expression actually had a C++ nested-name-specifier prior to the name ...
A pointer to member type per C++ 8.3.3 - Pointers to members.
QualType getPointeeType() const
Represents a C++ nested name specifier, such as "\::std::vector<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
Base for LValueReferenceType and RValueReferenceType.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
StringLiteral - This represents a string literal expression, e.g.
SourceLocation getBeginLoc() const
Get the begin source location.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isVoidPointerType() const
bool isPointerType() const
const T * castAs() const
Member-template castAs<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
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
AlignedAllocationMode alignedAllocationModeFromBool(bool IsAligned)
bool isAlignedAllocation(AlignedAllocationMode Mode)
const FunctionProtoType * T
@ Dtor_Complete
Complete object dtor.
@ Type
The name was classified as a type.
bool isTypeAwareAllocation(TypeAwareAllocationMode Mode)
LangAS
Defines the address space values used by the address space qualifier of QualType.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
U cast(CodeGen::Address addr)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getPointerSize() const
llvm::IntegerType * SizeTy
CharUnits getSizeAlign() const
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function.
static saved_type save(CodeGenFunction &CGF, type value)
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
TypeAwareAllocationMode TypeAwareDelete
AlignedAllocationMode Alignment