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};
85RValue CodeGenFunction::EmitCXXMemberOrOperatorCall(
88 llvm::Value *This, llvm::Value *ImplicitParam,
QualType ImplicitParamTy,
93 *
this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs);
95 Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize);
108 "Pointer/Object mixup");
112 if (SrcAS != DstAS) {
121 ImplicitParamTy, CE, Args,
nullptr);
142 BaseQuals = PTy->getPointeeType().getQualifiers();
183 return cast<CXXRecordDecl>(Ty->
getDecl());
192 if (isa<BinaryOperator>(callee))
195 const MemberExpr *ME = cast<MemberExpr>(callee);
219 assert(isa<CXXMemberCallExpr>(CE) || isa<CXXOperatorCallExpr>(CE));
222 bool CanUseVirtualCall = MD->
isVirtual() && !HasQualifier;
225 if (CanUseVirtualCall &&
229 assert(DevirtualizedMethod);
231 const Expr *Inner =
Base->IgnoreParenBaseCasts();
239 DevirtualizedMethod =
nullptr;
249 DevirtualizedMethod =
nullptr;
253 bool TrivialForCodegen =
255 bool TrivialAssignment =
264 LValue TrivialAssignmentRHS;
265 if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
266 if (OCE->isAssignmentOp()) {
267 if (TrivialAssignment) {
270 RtlArgs = &RtlArgStorage;
292 assert(
ReturnValue.isNull() &&
"Constructor shouldn't have return value");
300 false,
This.getAddress(*
this), Args,
306 if (TrivialForCodegen) {
307 if (isa<CXXDestructorDecl>(MD))
310 if (TrivialAssignment) {
316 LValue RHS = isa<CXXOperatorCallExpr>(CE)
317 ? TrivialAssignmentRHS
324 "unknown trivial member function");
329 DevirtualizedMethod ? DevirtualizedMethod : MD;
331 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl))
348 if (
const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
349 auto *IOA = CMCE->getImplicitObjectArgument();
351 if (IsImplicitObjectCXXThis)
352 SkippedChecks.
set(SanitizerKind::Alignment,
true);
353 if (IsImplicitObjectCXXThis || isa<DeclRefExpr>(IOA))
354 SkippedChecks.
set(SanitizerKind::Null,
true);
357 This.getPointer(*
this),
367 bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod;
371 "Destructor shouldn't have explicit parameters");
372 assert(
ReturnValue.isNull() &&
"Destructor shouldn't have return value");
373 if (UseVirtualCall) {
375 This.getAddress(*
this),
376 cast<CXXMemberCallExpr>(CE));
380 if (
getLangOpts().AppleKext && Dtor->isVirtual() && HasQualifier)
382 else if (!DevirtualizedMethod)
390 IsArrow ?
Base->getType()->getPointeeType() :
Base->getType();
402 if (UseVirtualCall) {
416 else if (!DevirtualizedMethod)
429 *
this, CalleeDecl,
This.getAddress(*
this), UseVirtualCall);
430 This.setAddress(NewThisAddr);
465 llvm::Value *ThisPtrForCall =
nullptr;
468 ThisPtrForCall, MemFnPtr, MPT);
493 "Trying to emit a member call expr on a static method!");
523 std::vector<CharUnits> VBPtrOffsets =
525 for (
CharUnits VBPtrOffset : VBPtrOffsets) {
527 if (VBPtrOffset >= NVSize)
529 std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val();
530 CharUnits LastStoreOffset = LastStore.first;
531 CharUnits LastStoreSize = LastStore.second;
533 CharUnits SplitBeforeOffset = LastStoreOffset;
534 CharUnits SplitBeforeSize = VBPtrOffset - SplitBeforeOffset;
535 assert(!SplitBeforeSize.
isNegative() &&
"negative store size!");
536 if (!SplitBeforeSize.
isZero())
537 Stores.emplace_back(SplitBeforeOffset, SplitBeforeSize);
539 CharUnits SplitAfterOffset = VBPtrOffset + VBPtrWidth;
540 CharUnits SplitAfterSize = LastStoreSize - SplitAfterOffset;
541 assert(!SplitAfterSize.
isNegative() &&
"negative store size!");
542 if (!SplitAfterSize.
isZero())
543 Stores.emplace_back(SplitAfterOffset, SplitAfterSize);
553 if (!NullConstantForBase->isNullValue()) {
554 llvm::GlobalVariable *NullVariable =
new llvm::GlobalVariable(
556 true, llvm::GlobalVariable::PrivateLinkage,
557 NullConstantForBase, Twine());
561 NullVariable->setAlignment(Align.
getAsAlign());
566 for (std::pair<CharUnits, CharUnits> Store : Stores) {
569 llvm::Value *StoreSizeVal = CGF.
CGM.
getSize(StoreSize);
580 for (std::pair<CharUnits, CharUnits> Store : Stores) {
583 llvm::Value *StoreSizeVal = CGF.
CGM.
getSize(StoreSize);
586 CGF.
Builder.getInt8(0), StoreSizeVal);
594 assert(!Dest.
isIgnored() &&
"Must have a destination!");
640 bool ForVirtualBase =
false;
655 ForVirtualBase =
true;
670 Exp = E->getSubExpr();
671 assert(isa<CXXConstructExpr>(Exp) &&
672 "EmitSynthesizedCXXCopyCtor - unknown copy ctor expr");
675 RunCleanupsScope
Scope(*
this);
685 &&
"EmitSynthesizedCXXCopyCtor - Copied-in Array");
704 unsigned minElements,
705 llvm::Value *&numElements,
706 llvm::Value *&sizeWithoutCookie) {
713 return sizeWithoutCookie;
717 unsigned sizeWidth = CGF.
SizeTy->getBitWidth();
720 llvm::APInt cookieSize(sizeWidth,
730 assert(isa<llvm::IntegerType>(numElements->getType()));
739 = (*e->
getArraySize())->getType()->isSignedIntegerOrEnumerationType();
740 llvm::IntegerType *numElementsType
741 = cast<llvm::IntegerType>(numElements->getType());
742 unsigned numElementsWidth = numElementsType->getBitWidth();
745 llvm::APInt arraySizeMultiplier(sizeWidth, 1);
748 type = CAT->getElementType();
749 arraySizeMultiplier *= CAT->getSize();
753 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.
getQuantity());
754 typeSizeMultiplier *= arraySizeMultiplier;
761 if (llvm::ConstantInt *numElementsC =
762 dyn_cast<llvm::ConstantInt>(numElements)) {
763 const llvm::APInt &count = numElementsC->getValue();
765 bool hasAnyOverflow =
false;
768 if (isSigned && count.isNegative())
769 hasAnyOverflow =
true;
774 else if (numElementsWidth > sizeWidth &&
775 numElementsWidth - sizeWidth > count.countl_zero())
776 hasAnyOverflow =
true;
779 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
783 if (adjustedCount.ult(minElements))
784 hasAnyOverflow =
true;
789 numElements = llvm::ConstantInt::get(CGF.
SizeTy,
790 adjustedCount * arraySizeMultiplier);
794 llvm::APInt allocationSize
795 = adjustedCount.umul_ov(typeSizeMultiplier, overflow);
796 hasAnyOverflow |= overflow;
799 if (cookieSize != 0) {
802 sizeWithoutCookie = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
804 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
805 hasAnyOverflow |= overflow;
809 if (hasAnyOverflow) {
810 size = llvm::Constant::getAllOnesValue(CGF.
SizeTy);
812 size = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
830 llvm::Value *hasOverflow =
nullptr;
835 if (numElementsWidth > sizeWidth) {
836 llvm::APInt threshold =
837 llvm::APInt::getOneBitSet(numElementsWidth, sizeWidth);
839 llvm::Value *thresholdV
840 = llvm::ConstantInt::get(numElementsType, threshold);
842 hasOverflow = CGF.
Builder.CreateICmpUGE(numElements, thresholdV);
843 numElements = CGF.
Builder.CreateTrunc(numElements, CGF.
SizeTy);
846 }
else if (isSigned) {
847 if (numElementsWidth < sizeWidth)
848 numElements = CGF.
Builder.CreateSExt(numElements, CGF.
SizeTy);
855 if (typeSizeMultiplier == 1)
856 hasOverflow = CGF.
Builder.CreateICmpSLT(numElements,
857 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
860 }
else if (numElementsWidth < sizeWidth) {
861 numElements = CGF.
Builder.CreateZExt(numElements, CGF.
SizeTy);
864 assert(numElements->getType() == CGF.
SizeTy);
869 hasOverflow = CGF.
Builder.CreateICmpULT(numElements,
870 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
871 }
else if (numElementsWidth > sizeWidth) {
875 hasOverflow = CGF.
Builder.CreateOr(hasOverflow,
876 CGF.
Builder.CreateICmpULT(numElements,
877 llvm::ConstantInt::get(CGF.
SizeTy, minElements)));
890 if (typeSizeMultiplier != 1) {
891 llvm::Function *umul_with_overflow
895 llvm::ConstantInt::get(CGF.
SizeTy, typeSizeMultiplier);
896 llvm::Value *result =
897 CGF.
Builder.CreateCall(umul_with_overflow, {size, tsmV});
899 llvm::Value *overflowed = CGF.
Builder.CreateExtractValue(result, 1);
901 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
903 hasOverflow = overflowed;
905 size = CGF.
Builder.CreateExtractValue(result, 0);
908 if (arraySizeMultiplier != 1) {
911 if (typeSize.
isOne()) {
912 assert(arraySizeMultiplier == typeSizeMultiplier);
918 llvm::ConstantInt::get(CGF.
SizeTy, arraySizeMultiplier);
919 numElements = CGF.
Builder.CreateMul(numElements, asmV);
924 assert(arraySizeMultiplier == 1);
928 if (cookieSize != 0) {
929 sizeWithoutCookie = size;
931 llvm::Function *uadd_with_overflow
934 llvm::Value *cookieSizeV = llvm::ConstantInt::get(CGF.
SizeTy, cookieSize);
935 llvm::Value *result =
936 CGF.
Builder.CreateCall(uadd_with_overflow, {size, cookieSizeV});
938 llvm::Value *overflowed = CGF.
Builder.CreateExtractValue(result, 1);
940 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
942 hasOverflow = overflowed;
944 size = CGF.
Builder.CreateExtractValue(result, 0);
951 size = CGF.
Builder.CreateSelect(hasOverflow,
952 llvm::Constant::getAllOnesValue(CGF.
SizeTy),
957 sizeWithoutCookie = size;
959 assert(sizeWithoutCookie &&
"didn't set sizeWithoutCookie?");
989 llvm_unreachable(
"bad evaluation kind");
994 Address BeginPtr, llvm::Value *NumElements,
995 llvm::Value *AllocSizeWithoutCookie) {
1003 unsigned InitListElements = 0;
1009 llvm::Instruction *CleanupDominator =
nullptr;
1016 auto TryMemsetInitialization = [&]() ->
bool {
1026 auto *RemainingSize = AllocSizeWithoutCookie;
1027 if (InitListElements) {
1029 auto *InitializedSize = llvm::ConstantInt::get(
1030 RemainingSize->getType(),
1031 getContext().getTypeSizeInChars(ElementType).getQuantity() *
1033 RemainingSize =
Builder.CreateSub(RemainingSize, InitializedSize);
1045 if (ILE->isStringLiteralInit()) {
1061 cast<ConstantArrayType>(ILE->getType()->getAsArrayTypeUnsafe())
1062 ->getSize().getZExtValue();
1064 CurPtr, InitListElements,
"string.init.end");
1067 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1068 if (!ConstNum || !ConstNum->equalsInt(InitListElements)) {
1069 bool OK = TryMemsetInitialization();
1071 assert(OK &&
"couldn't memset character type?");
1076 InitListElements = ILE->getNumInits();
1098 ElementType, ElementAlign,
1104 for (
unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) {
1115 ILE->getInit(i)->getType(), CurPtr,
1125 Init = ILE->getArrayFiller();
1130 while (
Init &&
Init->getType()->isConstantArrayType()) {
1131 auto *SubILE = dyn_cast<InitListExpr>(
Init);
1134 assert(SubILE->getNumInits() == 0 &&
"explicit inits in array filler?");
1135 Init = SubILE->getArrayFiller();
1144 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1145 if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
1147 if (CleanupDominator)
1152 assert(
Init &&
"have trailing elements to initialize but no initializer");
1164 if (TryMemsetInitialization())
1176 if (InitListElements)
1177 NumElements =
Builder.CreateSub(
1179 llvm::ConstantInt::get(NumElements->getType(), InitListElements));
1182 CCE->requiresZeroInitialization());
1188 if (isa<ImplicitValueInitExpr>(
Init)) {
1189 if (TryMemsetInitialization())
1200 assert(
getContext().hasSameUnqualifiedType(ElementType,
Init->getType()) &&
1201 "got wrong type of element to initialize");
1204 if (
auto *ILE = dyn_cast<InitListExpr>(
Init))
1205 if (ILE->getNumInits() == 0 && TryMemsetInitialization())
1210 if (
auto *ILE = dyn_cast<InitListExpr>(
Init)) {
1212 if (RType->getDecl()->isStruct()) {
1213 unsigned NumElements = 0;
1214 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RType->getDecl()))
1215 NumElements = CXXRD->getNumBases();
1216 for (
auto *Field : RType->getDecl()->fields())
1217 if (!
Field->isUnnamedBitfield())
1220 if (ILE->getNumInits() == NumElements)
1221 for (
unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
1222 if (!isa<ImplicitValueInitExpr>(ILE->getInit(i)))
1224 if (ILE->getNumInits() == NumElements && TryMemsetInitialization())
1231 llvm::BasicBlock *EntryBB =
Builder.GetInsertBlock();
1236 llvm::Value *EndPtr =
1238 NumElements,
"array.end");
1243 llvm::Value *IsEmpty =
1245 Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
1252 llvm::PHINode *CurPtrPhi =
1254 CurPtrPhi->addIncoming(CurPtr.
getPointer(), EntryBB);
1265 ElementType, ElementAlign,
1268 CleanupDominator =
Builder.CreateUnreachable();
1276 if (CleanupDominator) {
1278 CleanupDominator->eraseFromParent();
1282 llvm::Value *NextPtr =
1288 llvm::Value *IsEnd =
Builder.CreateICmpEQ(NextPtr, EndPtr,
"array.atend");
1289 Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
1290 CurPtrPhi->addIncoming(NextPtr,
Builder.GetInsertBlock());
1296 QualType ElementType, llvm::Type *ElementTy,
1297 Address NewPtr, llvm::Value *NumElements,
1298 llvm::Value *AllocSizeWithoutCookie) {
1302 AllocSizeWithoutCookie);
1314 llvm::CallBase *CallOrInvoke;
1319 Args, CalleeType,
false),
1327 llvm::Function *Fn = dyn_cast<llvm::Function>(CalleePtr);
1329 Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
1330 CallOrInvoke->addFnAttr(llvm::Attribute::Builtin);
1347 if (
auto *FD = dyn_cast<FunctionDecl>(
Decl))
1350 llvm_unreachable(
"predeclared global operator new/delete is missing");
1355struct UsualDeleteParams {
1356 bool DestroyingDelete =
false;
1358 bool Alignment =
false;
1363 UsualDeleteParams Params;
1373 Params.DestroyingDelete =
true;
1385 Params.Alignment =
true;
1389 assert(AI == AE &&
"unexpected usual deallocation function parameter");
1397 template<
typename Traits>
1400 typedef typename Traits::ValueTy ValueTy;
1402 typedef typename Traits::RValueTy RValueTy;
1403 struct PlacementArg {
1408 unsigned NumPlacementArgs : 31;
1409 unsigned PassAlignmentToPlacementDelete : 1;
1415 PlacementArg *getPlacementArgs() {
1416 return reinterpret_cast<PlacementArg *
>(
this + 1);
1420 static size_t getExtraSize(
size_t NumPlacementArgs) {
1421 return NumPlacementArgs *
sizeof(PlacementArg);
1424 CallDeleteDuringNew(
size_t NumPlacementArgs,
1426 ValueTy AllocSize,
bool PassAlignmentToPlacementDelete,
1428 : NumPlacementArgs(NumPlacementArgs),
1429 PassAlignmentToPlacementDelete(PassAlignmentToPlacementDelete),
1430 OperatorDelete(OperatorDelete), Ptr(Ptr), AllocSize(AllocSize),
1431 AllocAlign(AllocAlign) {}
1433 void setPlacementArg(
unsigned I, RValueTy Arg,
QualType Type) {
1434 assert(I < NumPlacementArgs &&
"index out of range");
1435 getPlacementArgs()[I] = {Arg,
Type};
1444 DeleteArgs.
add(Traits::get(CGF, Ptr), FPT->getParamType(0));
1447 UsualDeleteParams Params;
1448 if (NumPlacementArgs) {
1451 Params.Alignment = PassAlignmentToPlacementDelete;
1458 assert(!Params.DestroyingDelete &&
1459 "should not call destroying delete in a new-expression");
1463 DeleteArgs.add(Traits::get(CGF, AllocSize),
1470 if (Params.Alignment)
1471 DeleteArgs.add(
RValue::get(llvm::ConstantInt::get(
1476 for (
unsigned I = 0; I != NumPlacementArgs; ++I) {
1477 auto Arg = getPlacementArgs()[I];
1478 DeleteArgs.add(Traits::get(CGF, Arg.ArgValue), Arg.ArgType);
1492 llvm::Value *AllocSize,
1500 struct DirectCleanupTraits {
1501 typedef llvm::Value *ValueTy;
1507 typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
1509 DirectCleanup *Cleanup = CGF.
EHStack
1518 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1519 Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty);
1531 struct ConditionalCleanupTraits {
1535 return V.restore(CGF);
1538 typedef CallDeleteDuringNew<ConditionalCleanupTraits> ConditionalCleanup;
1540 ConditionalCleanup *Cleanup = CGF.
EHStack
1549 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1550 Cleanup->setPlacementArg(
1565 unsigned minElements = 0;
1571 ->getSize().getZExtValue();
1576 llvm::Value *numElements =
nullptr;
1577 llvm::Value *allocSizeWithoutCookie =
nullptr;
1578 llvm::Value *allocSize =
1580 allocSizeWithoutCookie);
1611 unsigned ParamsToSkip = 0;
1618 if (allocSize != allocSizeWithoutCookie) {
1620 allocAlign = std::max(allocAlign, cookieAlign);
1631 "wrong type for alignment parameter");
1635 assert(allocator->
isVariadic() &&
"can't pass alignment to allocator");
1644 AbstractCallee(), ParamsToSkip);
1651 if (
auto *newCall = dyn_cast<llvm::CallBase>(RV.
getScalarVal()))
1662 unsigned AllocatorAlign = llvm::bit_floor(std::min<uint64_t>(
1664 allocationAlign = std::max(
1665 allocationAlign,
getContext().toCharUnitsFromBits(AllocatorAlign));
1679 llvm::BasicBlock *nullCheckBB =
nullptr;
1680 llvm::BasicBlock *contBB =
nullptr;
1684 ConditionalEvaluation conditional(*
this);
1687 conditional.begin(*
this);
1689 nullCheckBB =
Builder.GetInsertBlock();
1693 llvm::Value *isNull =
1695 Builder.CreateCondBr(isNull, contBB, notNullBB);
1702 llvm::Instruction *cleanupDominator =
nullptr;
1708 cleanupDominator =
Builder.CreateUnreachable();
1711 assert((allocSize == allocSizeWithoutCookie) ==
1713 if (allocSize != allocSizeWithoutCookie) {
1737 SkippedChecks.
set(SanitizerKind::Null, nullCheck);
1741 SkippedChecks, numElements);
1744 allocSizeWithoutCookie);
1745 llvm::Value *resultPtr = result.
getPointer();
1751 if (resultPtr->getType() != resultType)
1752 resultPtr =
Builder.CreateBitCast(resultPtr, resultType);
1757 if (operatorDeleteCleanup.
isValid()) {
1759 cleanupDominator->eraseFromParent();
1763 conditional.end(*
this);
1765 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
1768 llvm::PHINode *PHI =
Builder.CreatePHI(resultPtr->getType(), 2);
1769 PHI->addIncoming(resultPtr, notNullBB);
1770 PHI->addIncoming(llvm::Constant::getNullValue(resultPtr->getType()),
1780 llvm::Value *Ptr,
QualType DeleteTy,
1781 llvm::Value *NumElements,
1783 assert((!NumElements && CookieSize.
isZero()) ||
1790 auto ParamTypeIt = DeleteFTy->param_type_begin();
1798 llvm::AllocaInst *DestroyingDeleteTag =
nullptr;
1799 if (Params.DestroyingDelete) {
1804 DestroyingDeleteTag->setAlignment(Align.
getAsAlign());
1811 QualType SizeType = *ParamTypeIt++;
1821 if (!CookieSize.
isZero())
1829 if (Params.Alignment) {
1830 QualType AlignValType = *ParamTypeIt++;
1834 llvm::Value *Align = llvm::ConstantInt::get(
ConvertType(AlignValType),
1839 assert(ParamTypeIt == DeleteFTy->param_type_end() &&
1840 "unknown parameter to usual delete function");
1847 if (DestroyingDeleteTag && DestroyingDeleteTag->use_empty())
1848 DestroyingDeleteTag->eraseFromParent();
1858 CallObjectDelete(llvm::Value *Ptr,
1861 : Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
1871 llvm::Value *CompletePtr,
1874 OperatorDelete, ElementType);
1885 if (Dtor && Dtor->isVirtual())
1899 llvm::BasicBlock *UnconditionalDeleteBlock) {
1921 bool UseVirtualCall =
true;
1923 if (
auto *DevirtualizedDtor =
1924 dyn_cast_or_null<const CXXDestructorDecl>(
1927 UseVirtualCall =
false;
1933 Dtor = DevirtualizedDtor;
1940 UseVirtualCall =
true;
1943 if (UseVirtualCall) {
1957 OperatorDelete, ElementType);
1983 CGF.
EmitBlock(UnconditionalDeleteBlock);
1997 llvm::Value *NumElements;
2001 CallArrayDelete(llvm::Value *Ptr,
2003 llvm::Value *NumElements,
2006 : Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
2007 ElementType(ElementType), CookieSize(CookieSize) {}
2010 CGF.
EmitDeleteCall(OperatorDelete, Ptr, ElementType, NumElements,
2021 llvm::Value *numElements =
nullptr;
2022 llvm::Value *allocatedPtr =
nullptr;
2025 numElements, allocatedPtr, cookieSize);
2027 assert(allocatedPtr &&
"ReadArrayCookie didn't set allocated pointer");
2032 allocatedPtr, operatorDelete,
2033 numElements, elementType,
2038 assert(numElements &&
"no element count for a type with a destructor!");
2044 llvm::Value *arrayBegin = deletedPtr.
getPointer();
2045 llvm::Value *arrayEnd = CGF.
Builder.CreateInBoundsGEP(
2046 deletedPtr.
getElementType(), arrayBegin, numElements,
"delete.end");
2098 GEP.push_back(Zero);
2102 =
getContext().getAsConstantArrayType(DeleteTy)) {
2104 DeleteTy = Arr->getElementType();
2107 GEP.push_back(Zero);
2130 if (
const auto *CE = dyn_cast<CastExpr>(E)) {
2136 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
2139 if (
const auto *BO = dyn_cast<BinaryOperator>(E))
2143 if (
const auto *ACO = dyn_cast<AbstractConditionalOperator>(E))
2149 if (isa<ArraySubscriptExpr>(E))
2152 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2153 if (UO->getOpcode() == UO_Deref)
2160 llvm::Type *StdTypeInfoPtrTy) {
2183 llvm::BasicBlock *BadTypeidBlock =
2200 llvm::Type *PtrTy = llvm::PointerType::getUnqual(
getLLVMContext());
2203 auto MaybeASCast = [=](
auto &&
TypeInfo) {
2233 return llvm::Constant::getNullValue(DestLTy);
2240 CGF.
Builder.ClearInsertionPoint();
2241 return llvm::PoisonValue::get(DestLTy);
2257 if (IsDynamicCastToVoid) {
2264 SrcRecordTy = SrcTy;
2279 if (!
Builder.GetInsertBlock())
2285 assert(SrcRecordTy->
isRecordType() &&
"source type must be a record type!");
2289 bool IsExact = !IsDynamicCastToVoid &&
2297 bool ShouldNullCheckSrcValue =
2301 llvm::BasicBlock *CastNull =
nullptr;
2302 llvm::BasicBlock *CastNotNull =
nullptr;
2305 if (ShouldNullCheckSrcValue) {
2315 if (IsDynamicCastToVoid) {
2317 }
else if (IsExact) {
2321 *
this, ThisAddr, SrcRecordTy, DestTy, DestRecordTy, CastEnd, CastNull);
2324 "destination type must be a record type!");
2326 DestTy, DestRecordTy, CastEnd);
2328 CastNotNull =
Builder.GetInsertBlock();
2330 llvm::Value *NullValue =
nullptr;
2331 if (ShouldNullCheckSrcValue) {
2336 CastNull =
Builder.GetInsertBlock();
2345 PHI->addIncoming(
Value, CastNotNull);
2346 PHI->addIncoming(NullValue, CastNull);
static MemberCallInfo commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, GlobalDecl GD, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE, CallArgList &Args, CallArgList *RtlArgs)
static llvm::Value * EmitDynamicCastToNull(CodeGenFunction &CGF, QualType DestTy)
static llvm::Value * EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, llvm::Type *StdTypeInfoPtrTy)
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 void EnterNewDeleteCleanup(CodeGenFunction &CGF, const CXXNewExpr *E, 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 bool isGLValueFromPointerDeref(const Expr *E)
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 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)
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.
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
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
std::optional< Expr * > getArraySize()
This might return std::nullopt even if isArray() returns true, since there might not be an array size...
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 C++ pseudo-destructor (C++ [expr.pseudo]).
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise,...
QualType getDestroyedType() const
Retrieve the type being destroyed.
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool isDynamicClass() const
bool hasDefinition() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
QualType getTypeOperand(ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
bool isTypeOperand() const
Expr * getExprOperand() const
bool isMostDerived(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....
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 LLVM_READONLY
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.
CharUnits getAlignment() const
Return the alignment of this pointer.
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.
KnownNonNull_t isKnownNonNull() const
Whether the pointer is known not to be null.
Address setKnownNonNull()
Set the non-null bit.
Address withAlignment(CharUnits NewAlignment) const
Return address with different alignment, but same pointer and element type.
llvm::Value * getPointer() const
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::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
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...
virtual RValue EmitCUDAKernelCallExpr(CodeGenFunction &CGF, const CUDAKernelCallExpr *E, ReturnValueSlot ReturnValue)
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 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 llvm::Value * EmitVirtualDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor, CXXDtorType DtorType, Address This, DeleteOrMemberCallExpr E)=0
Emit the ABI-specific virtual destructor call.
virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0
virtual llvm::Value * emitExactDynamicCast(CodeGenFunction &CGF, Address Value, QualType SrcRecordTy, QualType DestTy, QualType DestRecordTy, llvm::BasicBlock *CastSuccess, llvm::BasicBlock *CastFail)=0
Emit a dynamic_cast from SrcRecordTy to DestRecordTy.
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 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 bool shouldTypeidBeNullChecked(bool IsDeref, 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
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.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, Address This, Address Src, const CXXConstructExpr *E)
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
void EmitARCDestroyWeak(Address addr)
RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue)
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, QualType Type, CharUnits Alignment=CharUnits::Zero(), SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
Emit a check that V is the address of storage of the appropriate size and alignment for an object of ...
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void DeactivateCleanupBlock(EHScopeStack::stable_iterator Cleanup, llvm::Instruction *DominatingIP)
DeactivateCleanupBlock - Deactivates the given cleanup block.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
void pushIrregularPartialArrayCleanup(llvm::Value *arrayBegin, Address arrayEndPointer, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp)
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, bool NewPointerIsChecked, bool ZeroInitialization=false)
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E)
const LangOptions & getLangOpts() const
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, QualType elementType, CharUnits elementAlign, Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
RValue EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method, const CGCallee &Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E, CallArgList *RtlArgs)
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...
@ 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.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, bool IsMustTail, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::Type * ConvertTypeForMem(QualType T)
void EmitAggregateAssign(LValue Dest, LValue Src, QualType EltTy)
Emit an aggregate assignment.
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
@ ForceRightToLeft
! Language semantics require right-to-left evaluation.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType, llvm::Type *ElementTy, Address NewPtr, llvm::Value *NumElements, llvm::Value *AllocSizeWithoutCookie)
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...
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
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 EmitARCRelease(llvm::Value *value, ARCPreciseLifetime_t precise)
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, const CallExpr *TheCallExpr, bool IsDelete)
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, AggValueSlot ThisAVS, const CXXConstructExpr *E)
CGDebugInfo * getDebugInfo()
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
const TargetCodeGenInfo & getTargetHooks() const
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
ASTContext & getContext() const
CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD, NestedNameSpecifier *Qual, llvm::Type *Ty)
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue)
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest)
llvm::Type * ConvertType(QualType T)
llvm::Value * EmitCXXTypeidExpr(const CXXTypeidExpr *E)
RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue)
CodeGenTypes & getTypes() const
const TargetInfo & Target
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
const CallExpr * MustTailCall
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, ReturnValueSlot ReturnValue)
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, bool HasQualifier, NestedNameSpecifier *Qualifier, bool IsArrow, const Expr *Base)
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
static bool IsWrappedCXXThis(const Expr *E)
Check if E is a C++ "this" pointer wrapped in value-preserving casts.
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
const CodeGenOptions & getCodeGenOpts() const
LangAS GetGlobalVarAddressSpace(const VarDecl *D)
Return the AST address space of the underlying global variable for D, as determined by its declaratio...
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
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.
AlignmentSource getAlignmentSource() const
LValue - This represents an lvalue references.
Address getAddress(CodeGenFunction &CGF) 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)
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,...
virtual llvm::Value * performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, llvm::Value *V, LangAS SrcAddr, LangAS DestAddr, llvm::Type *DestTy, bool IsNonNull=false) const
Perform address space cast of an expression of pointer type.
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() const
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 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 isReplaceableGlobalAllocationFunction(std::optional< unsigned > *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
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
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
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 ...
NestedNameSpecifier * getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name.
A pointer to member type per C++ 8.3.3 - Pointers to members.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
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
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() 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.
unsigned getNewAlign() const
Return the largest alignment for which a suitably-sized allocation with '::operator new(size_t)' is g...
SourceLocation getBeginLoc() const
Get the begin source location.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
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 isConstantArrayType() const
bool isVoidPointerType() 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.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost 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.
bool This(InterpState &S, CodePtr OpPC)
bool Zero(InterpState &S, CodePtr OpPC)
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
@ Dtor_Complete
Complete object dtor.
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.
__DEVICE__ _Tp arg(const std::complex< _Tp > &__c)
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
CharUnits getPointerSize() const
llvm::IntegerType * SizeTy
CharUnits getSizeAlign() const
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.