22 #include "llvm/IR/Intrinsics.h" 24 using namespace clang;
25 using namespace CodeGen;
28 struct MemberCallInfo {
40 assert(CE ==
nullptr || isa<CXXMemberCallExpr>(CE) ||
41 isa<CXXOperatorCallExpr>(CE));
43 "Trying to emit a member or operator call expr on a static method!");
57 unsigned PrefixSize = Args.size() - 1;
67 unsigned ArgsToSkip = isa<CXXOperatorCallExpr>(CE) ? 1 : 0;
73 "No CallExpr specified for function with non-zero number of arguments");
75 return {required, PrefixSize};
86 *
this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs);
87 auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall(
88 Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize);
89 return EmitCall(FnInfo, Callee, ReturnValue, Args,
nullptr,
100 "Pointer/Object mixup");
104 if (SrcAS != DstAS) {
106 llvm::Type *NewType = CGM.getTypes().ConvertType(DstTy);
107 This = getTargetHooks().performAddrSpaceCast(*
this, This, SrcAS, DstAS,
113 ImplicitParamTy, CE, Args,
nullptr);
114 return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(Dtor), Callee,
131 BaseValue = EmitPointerWithAlignment(BaseExpr);
135 LValue BaseLV = EmitLValue(BaseExpr);
148 EmitARCRelease(Builder.CreateLoad(BaseValue,
154 EmitARCDestroyWeak(BaseValue);
174 return cast<CXXRecordDecl>(Ty->
getDecl());
183 if (isa<BinaryOperator>(callee))
184 return EmitCXXMemberPointerCallExpr(CE, ReturnValue);
186 const MemberExpr *ME = cast<MemberExpr>(callee);
189 if (MD->isStatic()) {
193 return EmitCall(getContext().getPointerType(MD->getType()), callee, CE,
202 return EmitCXXMemberOrOperatorMemberCallExpr(
203 CE, MD, ReturnValue, HasQualifier, Qualifier, IsArrow, Base);
210 assert(isa<CXXMemberCallExpr>(CE) || isa<CXXOperatorCallExpr>(CE));
213 bool CanUseVirtualCall = MD->
isVirtual() && !HasQualifier;
216 if (CanUseVirtualCall &&
220 assert(DevirtualizedMethod);
230 DevirtualizedMethod =
nullptr;
240 DevirtualizedMethod =
nullptr;
248 if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
249 if (OCE->isAssignmentOp()) {
250 RtlArgs = &RtlArgStorage;
253 0, EvaluationOrder::ForceRightToLeft);
261 Address ThisValue = EmitPointerWithAlignment(Base, &BaseInfo, &TBAAInfo);
262 This = MakeAddrLValue(ThisValue, Base->
getType(), BaseInfo, TBAAInfo);
264 This = EmitLValue(Base);
271 assert(ReturnValue.
isNull() &&
"Constructor shouldn't have return value");
274 *
this, Ctor, This.getPointer(),
nullptr,
278 false, This.getAddress(), Args,
285 if (isa<CXXDestructorDecl>(MD))
return RValue::get(
nullptr);
290 LValue RHS = isa<CXXOperatorCallExpr>(CE)
291 ? MakeNaturalAlignAddrLValue(
292 (*RtlArgs)[0].getRValue(*this).getScalarVal(),
295 EmitAggregateAssign(This, RHS, CE->
getType());
298 llvm_unreachable(
"unknown trivial member function");
304 DevirtualizedMethod ? DevirtualizedMethod : MD;
306 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl))
307 FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
310 FInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl);
312 llvm::FunctionType *Ty = CGM.getTypes().GetFunctionType(*FInfo);
323 if (
const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
324 auto *IOA = CMCE->getImplicitObjectArgument();
325 bool IsImplicitObjectCXXThis = IsWrappedCXXThis(IOA);
326 if (IsImplicitObjectCXXThis)
327 SkippedChecks.
set(SanitizerKind::Alignment,
true);
328 if (IsImplicitObjectCXXThis || isa<DeclRefExpr>(IOA))
329 SkippedChecks.
set(SanitizerKind::Null,
true);
341 bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod;
345 "Destructor shouldn't have explicit parameters");
346 assert(ReturnValue.
isNull() &&
"Destructor shouldn't have return value");
347 if (UseVirtualCall) {
348 CGM.getCXXABI().EmitVirtualDestructorCall(
350 cast<CXXMemberCallExpr>(CE));
354 if (getLangOpts().AppleKext && Dtor->isVirtual() && HasQualifier)
356 else if (!DevirtualizedMethod)
365 EmitCXXDestructorCall(GD, Callee, This.getPointer(), ThisTy,
376 if (UseVirtualCall) {
379 if (SanOpts.has(SanitizerKind::CFINVCall) &&
383 std::tie(VTable, RD) =
384 CGM.getCXXABI().LoadVTablePtr(*
this, This.getAddress(),
386 EmitVTablePtrCheckForCall(RD, VTable, CFITCK_NVCall, CE->
getBeginLoc());
389 if (getLangOpts().AppleKext && MD->
isVirtual() && HasQualifier)
391 else if (!DevirtualizedMethod)
403 CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
404 *
this, CalleeDecl, This.getAddress(), UseVirtualCall);
405 This.setAddress(NewThisAddr);
408 return EmitCXXMemberOrOperatorCall(
409 CalleeDecl, Callee, ReturnValue, This.getPointer(),
432 This = EmitPointerWithAlignment(BaseExpr);
434 This = EmitLValue(BaseExpr).getAddress();
436 EmitTypeCheck(TCK_MemberCall, E->
getExprLoc(), This.getPointer(),
445 CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*
this, BO, This,
446 ThisPtrForCall, MemFnPtr, MPT);
451 getContext().getPointerType(getContext().getTagDeclType(RD));
460 return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required,
462 Callee, ReturnValue, Args,
nullptr, E->
getExprLoc());
470 "Trying to emit a member call expr on a static method!");
471 return EmitCXXMemberOrOperatorMemberCallExpr(
472 E, MD, ReturnValue,
false,
nullptr,
478 return CGM.getCUDARuntime().EmitCUDAKernelCallExpr(*
this, E, ReturnValue);
500 std::vector<CharUnits> VBPtrOffsets =
502 for (
CharUnits VBPtrOffset : VBPtrOffsets) {
504 if (VBPtrOffset >= NVSize)
506 std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val();
507 CharUnits LastStoreOffset = LastStore.first;
508 CharUnits LastStoreSize = LastStore.second;
510 CharUnits SplitBeforeOffset = LastStoreOffset;
511 CharUnits SplitBeforeSize = VBPtrOffset - SplitBeforeOffset;
512 assert(!SplitBeforeSize.
isNegative() &&
"negative store size!");
513 if (!SplitBeforeSize.
isZero())
514 Stores.emplace_back(SplitBeforeOffset, SplitBeforeSize);
516 CharUnits SplitAfterOffset = VBPtrOffset + VBPtrWidth;
517 CharUnits SplitAfterSize = LastStoreSize - SplitAfterOffset;
518 assert(!SplitAfterSize.
isNegative() &&
"negative store size!");
519 if (!SplitAfterSize.
isZero())
520 Stores.emplace_back(SplitAfterOffset, SplitAfterSize);
530 if (!NullConstantForBase->isNullValue()) {
531 llvm::GlobalVariable *NullVariable =
new llvm::GlobalVariable(
533 true, llvm::GlobalVariable::PrivateLinkage,
534 NullConstantForBase, Twine());
538 NullVariable->setAlignment(Align.getQuantity());
543 for (std::pair<CharUnits, CharUnits>
Store : Stores) {
557 for (std::pair<CharUnits, CharUnits>
Store : Stores) {
563 CGF.
Builder.getInt8(0), StoreSizeVal);
571 assert(!Dest.
isIgnored() &&
"Must have a destination!");
593 if (CD->isTrivial() && CD->isDefaultConstructor())
599 if (getLangOpts().ElideConstructors && E->
isElidable()) {
600 assert(getContext().hasSameUnqualifiedType(E->
getType(),
603 EmitAggExpr(E->
getArg(0), Dest);
609 = getContext().getAsArrayType(E->
getType())) {
614 bool ForVirtualBase =
false;
615 bool Delegating =
false;
620 Type = CurGD.getCtorType();
629 ForVirtualBase =
true;
637 EmitCXXConstructorCall(CD, Type, ForVirtualBase, Delegating, Dest, E);
644 Exp = E->getSubExpr();
645 assert(isa<CXXConstructExpr>(Exp) &&
646 "EmitSynthesizedCXXCopyCtor - unknown copy ctor expr");
656 EmitNullInitialization(Dest, E->
getType());
658 assert(!getContext().getAsConstantArrayType(E->
getType())
659 &&
"EmitSynthesizedCXXCopyCtor - Copied-in Array");
660 EmitSynthesizedCXXCopyCtorCall(CD, Dest, Src, E);
678 unsigned minElements,
687 return sizeWithoutCookie;
691 unsigned sizeWidth = CGF.
SizeTy->getBitWidth();
694 llvm::APInt cookieSize(sizeWidth,
704 assert(isa<llvm::IntegerType>(numElements->getType()));
713 = (*e->
getArraySize())->getType()->isSignedIntegerOrEnumerationType();
714 llvm::IntegerType *numElementsType
715 = cast<llvm::IntegerType>(numElements->getType());
716 unsigned numElementsWidth = numElementsType->getBitWidth();
719 llvm::APInt arraySizeMultiplier(sizeWidth, 1);
722 type = CAT->getElementType();
723 arraySizeMultiplier *= CAT->getSize();
727 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.
getQuantity());
728 typeSizeMultiplier *= arraySizeMultiplier;
735 if (llvm::ConstantInt *numElementsC =
736 dyn_cast<llvm::ConstantInt>(numElements)) {
737 const llvm::APInt &count = numElementsC->getValue();
739 bool hasAnyOverflow =
false;
742 if (isSigned && count.isNegative())
743 hasAnyOverflow =
true;
748 else if (numElementsWidth > sizeWidth &&
749 numElementsWidth - sizeWidth > count.countLeadingZeros())
750 hasAnyOverflow =
true;
753 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
757 if (adjustedCount.ult(minElements))
758 hasAnyOverflow =
true;
763 numElements = llvm::ConstantInt::get(CGF.
SizeTy,
764 adjustedCount * arraySizeMultiplier);
768 llvm::APInt allocationSize
769 = adjustedCount.umul_ov(typeSizeMultiplier, overflow);
770 hasAnyOverflow |= overflow;
773 if (cookieSize != 0) {
776 sizeWithoutCookie = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
778 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
779 hasAnyOverflow |= overflow;
783 if (hasAnyOverflow) {
784 size = llvm::Constant::getAllOnesValue(CGF.
SizeTy);
786 size = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
809 if (numElementsWidth > sizeWidth) {
810 llvm::APInt threshold(numElementsWidth, 1);
811 threshold <<= sizeWidth;
814 = llvm::ConstantInt::get(numElementsType, threshold);
816 hasOverflow = CGF.
Builder.CreateICmpUGE(numElements, thresholdV);
817 numElements = CGF.
Builder.CreateTrunc(numElements, CGF.
SizeTy);
820 }
else if (isSigned) {
821 if (numElementsWidth < sizeWidth)
822 numElements = CGF.
Builder.CreateSExt(numElements, CGF.
SizeTy);
829 if (typeSizeMultiplier == 1)
830 hasOverflow = CGF.
Builder.CreateICmpSLT(numElements,
831 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
834 }
else if (numElementsWidth < sizeWidth) {
835 numElements = CGF.
Builder.CreateZExt(numElements, CGF.
SizeTy);
838 assert(numElements->getType() == CGF.
SizeTy);
843 hasOverflow = CGF.
Builder.CreateICmpULT(numElements,
844 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
845 }
else if (numElementsWidth > sizeWidth) {
849 hasOverflow = CGF.
Builder.CreateOr(hasOverflow,
850 CGF.
Builder.CreateICmpULT(numElements,
851 llvm::ConstantInt::get(CGF.
SizeTy, minElements)));
864 if (typeSizeMultiplier != 1) {
865 llvm::Function *umul_with_overflow
869 llvm::ConstantInt::get(CGF.
SizeTy, typeSizeMultiplier);
871 CGF.
Builder.CreateCall(umul_with_overflow, {size, tsmV});
875 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
877 hasOverflow = overflowed;
879 size = CGF.
Builder.CreateExtractValue(result, 0);
882 if (arraySizeMultiplier != 1) {
885 if (typeSize.
isOne()) {
886 assert(arraySizeMultiplier == typeSizeMultiplier);
892 llvm::ConstantInt::get(CGF.
SizeTy, arraySizeMultiplier);
893 numElements = CGF.
Builder.CreateMul(numElements, asmV);
898 assert(arraySizeMultiplier == 1);
902 if (cookieSize != 0) {
903 sizeWithoutCookie = size;
905 llvm::Function *uadd_with_overflow
910 CGF.
Builder.CreateCall(uadd_with_overflow, {size, cookieSizeV});
914 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
916 hasOverflow = overflowed;
918 size = CGF.
Builder.CreateExtractValue(result, 0);
925 size = CGF.
Builder.CreateSelect(hasOverflow,
926 llvm::Constant::getAllOnesValue(CGF.
SizeTy),
931 sizeWithoutCookie = size;
933 assert(sizeWithoutCookie &&
"didn't set sizeWithoutCookie?");
963 llvm_unreachable(
"bad evaluation kind");
977 unsigned InitListElements = 0;
983 llvm::Instruction *CleanupDominator =
nullptr;
985 CharUnits ElementSize = getContext().getTypeSizeInChars(ElementType);
990 auto TryMemsetInitialization = [&]() ->
bool {
993 if (!CGM.getTypes().isZeroInitializable(ElementType))
1000 auto *RemainingSize = AllocSizeWithoutCookie;
1001 if (InitListElements) {
1003 auto *InitializedSize = llvm::ConstantInt::get(
1004 RemainingSize->getType(),
1005 getContext().getTypeSizeInChars(ElementType).getQuantity() *
1007 RemainingSize = Builder.CreateSub(RemainingSize, InitializedSize);
1011 Builder.CreateMemSet(CurPtr, Builder.getInt8(0), RemainingSize,
false);
1016 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
1019 if (ILE->isStringLiteralInit()) {
1031 EmitAggExpr(ILE->getInit(0), Slot);
1035 cast<ConstantArrayType>(ILE->getType()->getAsArrayTypeUnsafe())
1036 ->getSize().getZExtValue();
1039 Builder.getSize(InitListElements),
1045 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1046 if (!ConstNum || !ConstNum->equalsInt(InitListElements)) {
1047 bool OK = TryMemsetInitialization();
1049 assert(OK &&
"couldn't memset character type?");
1054 InitListElements = ILE->getNumInits();
1061 ElementTy = ConvertTypeForMem(AllocType);
1062 CurPtr = Builder.CreateElementBitCast(CurPtr, ElementTy);
1063 InitListElements *= getContext().getConstantArrayElementCount(CAT);
1067 if (needsEHCleanup(DtorKind)) {
1072 EndOfInit = CreateTempAlloca(BeginPtr.
getType(), getPointerAlign(),
1074 CleanupDominator = Builder.CreateStore(BeginPtr.
getPointer(), EndOfInit);
1075 pushIrregularPartialArrayCleanup(BeginPtr.
getPointer(), EndOfInit,
1076 ElementType, ElementAlign,
1077 getDestroyer(DtorKind));
1078 Cleanup = EHStack.stable_begin();
1082 for (
unsigned i = 0, e = ILE->getNumInits();
i != e; ++
i) {
1089 Builder.CreateStore(FinishedPtr, EndOfInit);
1095 ILE->getInit(
i)->getType(), CurPtr,
1097 CurPtr =
Address(Builder.CreateInBoundsGEP(CurPtr.getPointer(),
1104 Init = ILE->getArrayFiller();
1109 while (Init && Init->
getType()->isConstantArrayType()) {
1113 assert(SubILE->getNumInits() == 0 &&
"explicit inits in array filler?");
1114 Init = SubILE->getArrayFiller();
1118 CurPtr = Builder.CreateBitCast(CurPtr, BeginPtr.
getType());
1123 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1124 if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
1126 if (CleanupDominator)
1127 DeactivateCleanupBlock(Cleanup, CleanupDominator);
1131 assert(Init &&
"have trailing elements to initialize but no initializer");
1143 if (TryMemsetInitialization())
1152 Builder.CreateStore(CurPtr.
getPointer(), EndOfInit);
1155 if (InitListElements)
1156 NumElements = Builder.CreateSub(
1158 llvm::ConstantInt::get(NumElements->getType(), InitListElements));
1159 EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE,
1161 CCE->requiresZeroInitialization());
1167 if (isa<ImplicitValueInitExpr>(Init)) {
1168 if (TryMemsetInitialization())
1179 assert(getContext().hasSameUnqualifiedType(ElementType, Init->
getType()) &&
1180 "got wrong type of element to initialize");
1183 if (
auto *ILE = dyn_cast<InitListExpr>(Init))
1184 if (ILE->getNumInits() == 0 && TryMemsetInitialization())
1189 if (
auto *ILE = dyn_cast<InitListExpr>(Init)) {
1191 if (RType->getDecl()->isStruct()) {
1192 unsigned NumElements = 0;
1193 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RType->getDecl()))
1194 NumElements = CXXRD->getNumBases();
1195 for (
auto *Field : RType->getDecl()->fields())
1196 if (!Field->isUnnamedBitfield())
1199 if (ILE->getNumInits() == NumElements)
1200 for (
unsigned i = 0, e = ILE->getNumInits();
i != e; ++
i)
1201 if (!isa<ImplicitValueInitExpr>(ILE->getInit(
i)))
1203 if (ILE->getNumInits() == NumElements && TryMemsetInitialization())
1210 llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
1211 llvm::BasicBlock *LoopBB = createBasicBlock(
"new.loop");
1212 llvm::BasicBlock *ContBB = createBasicBlock(
"new.loop.end");
1216 Builder.CreateInBoundsGEP(BeginPtr.
getPointer(), NumElements,
"array.end");
1222 Builder.CreateICmpEQ(CurPtr.
getPointer(), EndPtr,
"array.isempty");
1223 Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
1230 llvm::PHINode *CurPtrPhi =
1231 Builder.CreatePHI(CurPtr.
getType(), 2,
"array.cur");
1232 CurPtrPhi->addIncoming(CurPtr.
getPointer(), EntryBB);
1234 CurPtr =
Address(CurPtrPhi, ElementAlign);
1238 Builder.CreateStore(CurPtr.
getPointer(), EndOfInit);
1241 if (!CleanupDominator && needsEHCleanup(DtorKind)) {
1243 ElementType, ElementAlign,
1244 getDestroyer(DtorKind));
1245 Cleanup = EHStack.stable_begin();
1246 CleanupDominator = Builder.CreateUnreachable();
1254 if (CleanupDominator) {
1255 DeactivateCleanupBlock(Cleanup, CleanupDominator);
1256 CleanupDominator->eraseFromParent();
1261 Builder.CreateConstInBoundsGEP1_32(ElementTy, CurPtr.
getPointer(), 1,
1266 llvm::Value *IsEnd = Builder.CreateICmpEQ(NextPtr, EndPtr,
"array.atend");
1267 Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
1268 CurPtrPhi->addIncoming(NextPtr, Builder.GetInsertBlock());
1280 AllocSizeWithoutCookie);
1292 llvm::CallBase *CallOrInvoke;
1297 Args, CalleeType,
false),
1305 llvm::Function *Fn = dyn_cast<llvm::Function>(CalleePtr);
1307 Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
1308 CallOrInvoke->addAttribute(llvm::AttributeList::FunctionIndex,
1309 llvm::Attribute::Builtin);
1323 .getCXXOperatorName(IsDelete ? OO_Delete : OO_New);
1326 if (
auto *FD = dyn_cast<FunctionDecl>(
Decl))
1327 if (Ctx.hasSameType(FD->getType(),
QualType(Type, 0)))
1329 llvm_unreachable(
"predeclared global operator new/delete is missing");
1334 struct UsualDeleteParams {
1335 bool DestroyingDelete =
false;
1337 bool Alignment =
false;
1342 UsualDeleteParams Params;
1352 Params.DestroyingDelete =
true;
1364 Params.Alignment =
true;
1368 assert(AI == AE &&
"unexpected usual deallocation function parameter");
1376 template<
typename Traits>
1379 typedef typename Traits::ValueTy ValueTy;
1381 typedef typename Traits::RValueTy RValueTy;
1382 struct PlacementArg {
1387 unsigned NumPlacementArgs : 31;
1388 unsigned PassAlignmentToPlacementDelete : 1;
1394 PlacementArg *getPlacementArgs() {
1395 return reinterpret_cast<PlacementArg *
>(
this + 1);
1399 static size_t getExtraSize(
size_t NumPlacementArgs) {
1400 return NumPlacementArgs *
sizeof(PlacementArg);
1403 CallDeleteDuringNew(
size_t NumPlacementArgs,
1405 ValueTy AllocSize,
bool PassAlignmentToPlacementDelete,
1407 : NumPlacementArgs(NumPlacementArgs),
1408 PassAlignmentToPlacementDelete(PassAlignmentToPlacementDelete),
1409 OperatorDelete(OperatorDelete), Ptr(Ptr), AllocSize(AllocSize),
1410 AllocAlign(AllocAlign) {}
1412 void setPlacementArg(
unsigned I, RValueTy Arg,
QualType Type) {
1413 assert(I < NumPlacementArgs &&
"index out of range");
1414 getPlacementArgs()[I] = {Arg, Type};
1427 UsualDeleteParams Params;
1428 if (NumPlacementArgs) {
1431 Params.Alignment = PassAlignmentToPlacementDelete;
1438 assert(!Params.DestroyingDelete &&
1439 "should not call destroying delete in a new-expression");
1443 DeleteArgs.add(Traits::get(CGF, AllocSize),
1450 if (Params.Alignment)
1451 DeleteArgs.add(
RValue::get(llvm::ConstantInt::get(
1456 for (
unsigned I = 0; I != NumPlacementArgs; ++I) {
1457 auto Arg = getPlacementArgs()[I];
1458 DeleteArgs.add(Traits::get(CGF, Arg.ArgValue), Arg.ArgType);
1480 struct DirectCleanupTraits {
1484 static RValue get(CodeGenFunction &, RValueTy
V) {
return V; }
1487 typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
1489 DirectCleanup *Cleanup = CGF.
EHStack 1498 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1499 Cleanup->setPlacementArg(I, Arg.getRValue(CGF), Arg.Ty);
1511 struct ConditionalCleanupTraits {
1515 return V.restore(CGF);
1518 typedef CallDeleteDuringNew<ConditionalCleanupTraits> ConditionalCleanup;
1520 ConditionalCleanup *Cleanup = CGF.
EHStack 1529 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1530 Cleanup->setPlacementArg(
1545 unsigned minElements = 0;
1551 ->getSize().getZExtValue();
1560 allocSizeWithoutCookie);
1561 CharUnits allocAlign = getContext().getTypeAlignInChars(allocType);
1572 allocation = EmitPointerWithAlignment(arg, &BaseInfo);
1584 allocatorArgs.
add(
RValue::get(allocSize), getContext().getSizeType());
1591 unsigned ParamsToSkip = 0;
1594 QualType sizeType = getContext().getSizeType();
1598 if (allocSize != allocSizeWithoutCookie) {
1600 allocAlign =
std::max(allocAlign, cookieAlign);
1608 assert(getContext().hasSameUnqualifiedType(
1611 "wrong type for alignment parameter");
1615 assert(allocator->
isVariadic() &&
"can't pass alignment to allocator");
1636 unsigned AllocatorAlign = llvm::PowerOf2Floor(std::min<uint64_t>(
1637 Target.getNewAlign(), getContext().getTypeSize(allocType)));
1639 allocationAlign, getContext().toCharUnitsFromBits(AllocatorAlign));
1642 allocation =
Address(RV.getScalarVal(), allocationAlign);
1651 sanitizePerformTypeCheck());
1653 llvm::BasicBlock *nullCheckBB =
nullptr;
1654 llvm::BasicBlock *contBB =
nullptr;
1661 conditional.
begin(*
this);
1663 nullCheckBB = Builder.GetInsertBlock();
1664 llvm::BasicBlock *notNullBB = createBasicBlock(
"new.notnull");
1665 contBB = createBasicBlock(
"new.cont");
1668 Builder.CreateIsNull(allocation.
getPointer(),
"new.isnull");
1669 Builder.CreateCondBr(isNull, contBB, notNullBB);
1670 EmitBlock(notNullBB);
1676 llvm::Instruction *cleanupDominator =
nullptr;
1681 operatorDeleteCleanup = EHStack.stable_begin();
1682 cleanupDominator = Builder.CreateUnreachable();
1685 assert((allocSize == allocSizeWithoutCookie) ==
1687 if (allocSize != allocSizeWithoutCookie) {
1689 allocation = CGM.getCXXABI().InitializeArrayCookie(*
this, allocation,
1694 llvm::Type *elementTy = ConvertTypeForMem(allocType);
1695 Address result = Builder.CreateElementBitCast(allocation, elementTy);
1701 if (CGM.getCodeGenOpts().StrictVTablePointers &&
1712 SkippedChecks.
set(SanitizerKind::Null, nullCheck);
1716 SkippedChecks, numElements);
1719 allocSizeWithoutCookie);
1725 if (result.
getType() != resultType)
1726 result = Builder.CreateBitCast(result, resultType);
1731 if (operatorDeleteCleanup.
isValid()) {
1732 DeactivateCleanupBlock(operatorDeleteCleanup, cleanupDominator);
1733 cleanupDominator->eraseFromParent();
1738 conditional.
end(*
this);
1740 llvm::BasicBlock *notNullBB = Builder.GetInsertBlock();
1743 llvm::PHINode *PHI = Builder.CreatePHI(resultPtr->getType(), 2);
1744 PHI->addIncoming(resultPtr, notNullBB);
1745 PHI->addIncoming(llvm::Constant::getNullValue(resultPtr->getType()),
1758 assert((!NumElements && CookieSize.
isZero()) ||
1767 auto ParamTypeIt = DeleteFTy->param_type_begin();
1771 llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
1775 if (Params.DestroyingDelete) {
1778 auto *
V = llvm::UndefValue::get(getTypes().ConvertType(DDTag));
1784 QualType SizeType = *ParamTypeIt++;
1785 CharUnits DeleteTypeSize = getContext().getTypeSizeInChars(DeleteTy);
1786 llvm::Value *Size = llvm::ConstantInt::get(ConvertType(SizeType),
1791 Size = Builder.CreateMul(Size, NumElements);
1794 if (!CookieSize.
isZero())
1795 Size = Builder.CreateAdd(
1796 Size, llvm::ConstantInt::get(SizeTy, CookieSize.
getQuantity()));
1802 if (Params.Alignment) {
1803 QualType AlignValType = *ParamTypeIt++;
1804 CharUnits DeleteTypeAlign = getContext().toCharUnitsFromBits(
1805 getContext().getTypeAlignIfKnown(DeleteTy));
1806 llvm::Value *Align = llvm::ConstantInt::get(ConvertType(AlignValType),
1811 assert(ParamTypeIt == DeleteFTy->param_type_end() &&
1812 "unknown parameter to usual delete function");
1828 : Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
1841 OperatorDelete, ElementType);
1852 if (Dtor && Dtor->isVirtual())
1884 if (Dtor->isVirtual()) {
1897 OperatorDelete, ElementType);
1938 : Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
1939 ElementType(ElementType), CookieSize(CookieSize) {}
1942 CGF.
EmitDeleteCall(OperatorDelete, Ptr, ElementType, NumElements,
1957 numElements, allocatedPtr, cookieSize);
1959 assert(allocatedPtr &&
"ReadArrayCookie didn't set allocated pointer");
1964 allocatedPtr, operatorDelete,
1965 numElements, elementType,
1970 assert(numElements &&
"no element count for a type with a destructor!");
1978 CGF.
Builder.CreateInBoundsGEP(arrayBegin, numElements,
"delete.end");
1995 Address Ptr = EmitPointerWithAlignment(Arg);
1998 llvm::BasicBlock *DeleteNotNull = createBasicBlock(
"delete.notnull");
1999 llvm::BasicBlock *DeleteEnd = createBasicBlock(
"delete.end");
2003 Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
2004 EmitBlock(DeleteNotNull);
2012 EmitBlock(DeleteEnd);
2023 GEP.push_back(Zero);
2027 = getContext().getAsConstantArrayType(DeleteTy)) {
2029 DeleteTy = Arr->getElementType();
2032 GEP.push_back(Zero);
2047 EmitBlock(DeleteEnd);
2053 if (
const auto *CE = dyn_cast<CastExpr>(E)) {
2054 if (!CE->getSubExpr()->isGLValue())
2059 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
2062 if (
const auto *BO = dyn_cast<BinaryOperator>(E))
2063 if (BO->getOpcode() == BO_Comma)
2066 if (
const auto *ACO = dyn_cast<AbstractConditionalOperator>(E))
2072 if (isa<ArraySubscriptExpr>(E))
2075 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2076 if (UO->getOpcode() == UO_Deref)
2106 llvm::BasicBlock *BadTypeidBlock =
2111 CGF.
Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock);
2124 ConvertType(E->
getType())->getPointerTo();
2129 return Builder.CreateBitCast(TypeInfo, StdTypeInfoPtrTy);
2142 return Builder.CreateBitCast(CGM.GetAddrOfRTTIDescriptor(OperandTy),
2150 return llvm::Constant::getNullValue(DestLTy);
2158 return llvm::UndefValue::get(DestLTy);
2163 CGM.EmitExplicitCastExprType(DCE,
this);
2173 bool isDynamicCastToVoid;
2181 isDynamicCastToVoid =
false;
2182 SrcRecordTy = SrcTy;
2198 assert(SrcRecordTy->
isRecordType() &&
"source type must be a record type!");
2203 bool ShouldNullCheckSrcValue =
2204 CGM.getCXXABI().shouldDynamicCastCallBeNullChecked(SrcTy->
isPointerType(),
2207 llvm::BasicBlock *CastNull =
nullptr;
2208 llvm::BasicBlock *CastNotNull =
nullptr;
2209 llvm::BasicBlock *CastEnd = createBasicBlock(
"dynamic_cast.end");
2211 if (ShouldNullCheckSrcValue) {
2212 CastNull = createBasicBlock(
"dynamic_cast.null");
2213 CastNotNull = createBasicBlock(
"dynamic_cast.notnull");
2216 Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
2217 EmitBlock(CastNotNull);
2221 if (isDynamicCastToVoid) {
2222 Value = CGM.getCXXABI().EmitDynamicCastToVoid(*
this, ThisAddr, SrcRecordTy,
2226 "destination type must be a record type!");
2227 Value = CGM.getCXXABI().EmitDynamicCastCall(*
this, ThisAddr, SrcRecordTy,
2228 DestTy, DestRecordTy, CastEnd);
2229 CastNotNull = Builder.GetInsertBlock();
2232 if (ShouldNullCheckSrcValue) {
2233 EmitBranch(CastEnd);
2235 EmitBlock(CastNull);
2236 EmitBranch(CastEnd);
2241 if (ShouldNullCheckSrcValue) {
2242 llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2);
2243 PHI->addIncoming(Value, CastNotNull);
2244 PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull);
A call to an overloaded operator written using operator syntax.
ReturnValueSlot - Contains the address where the return value of a function can be stored...
virtual void EmitBadTypeidCall(CodeGenFunction &CGF)=0
CanQualType DeriveThisType(const CXXRecordDecl *RD, const CXXMethodDecl *MD)
Derives the 'this' type for codegen purposes, i.e.
Represents a function declaration or definition.
bool isReservedGlobalPlacementOperator() const
Determines whether this operator new or delete is one of the reserved global placement operators: voi...
Address getAddress() const
void end(CodeGenFunction &CGF)
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
llvm::iterator_range< arg_iterator > placement_arguments()
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
A (possibly-)qualified type.
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 ...
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
CodeGenTypes & getTypes()
static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF, GlobalDecl GD, llvm::Type *Ty, const CXXRecordDecl *RD)
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
void EmitARCDestroyWeak(Address addr)
void @objc_destroyWeak(i8** addr) Essentially objc_storeWeak(addr, nil).
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
void EmitNewArrayInitializer(const CXXNewExpr *E, QualType elementType, llvm::Type *ElementTy, Address NewPtr, llvm::Value *NumElements, llvm::Value *AllocSizeWithoutCookie)
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
virtual bool shouldTypeidBeNullChecked(bool IsDeref, QualType SrcRecordTy)=0
QualType getThisType() const
Return the type of the this pointer.
Checking the 'this' pointer for a constructor call.
bool isRecordType() const
Decl - This represents one declaration (or definition), e.g.
CharUnits getPointerSize() const
FunctionDecl * getOperatorNew() const
bool hasQualifier() const
Determines whether this member expression actually had a C++ nested-name-specifier prior to the name ...
The base class of the type hierarchy.
bool requiresZeroInitialization() const
Whether this construction first requires zero-initialization before the initializer is called...
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a call to a C++ constructor.
RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue)
bool isZero() const
isZero - Test whether the quantity equals zero.
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
Expr * ignoreParenBaseCasts() LLVM_READONLY
Skip past any parentheses and derived-to-base casts until reaching a fixed point. ...
static llvm::Value * EmitCXXNewAllocSize(CodeGenFunction &CGF, const CXXNewExpr *e, unsigned minElements, llvm::Value *&numElements, llvm::Value *&sizeWithoutCookie)
static saved_type save(CodeGenFunction &CGF, type value)
QualType getReturnType() const
unsigned getNumParams() const
const T * getAs() const
Member-template getAs<specific type>'.
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
LangAS
Defines the address space values used by the address space qualifier of QualType. ...
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
IsZeroed_t isZeroed() const
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * getPointer() const
unsigned getNumPlacementArgs() const
static MemberCallInfo commonEmitCXXMemberOrOperatorCall(CodeGenFunction &CGF, const CXXMethodDecl *MD, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *CE, CallArgList &Args, CallArgList *RtlArgs)
RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, ReturnValueSlot ReturnValue)
bool hasDefinition() const
Expr * getExprOperand() const
Represents an expression – generally a full-expression – that introduces cleanups to be run at the ...
RValue EmitCXXMemberOrOperatorCall(const CXXMethodDecl *Method, const CGCallee &Callee, ReturnValueSlot ReturnValue, llvm::Value *This, llvm::Value *ImplicitParam, QualType ImplicitParamTy, const CallExpr *E, CallArgList *RtlArgs)
The collection of all-type qualifiers we support.
void add(RValue rvalue, QualType type)
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
An object to manage conditionally-evaluated expressions.
llvm::Value * EmitCXXNewExpr(const CXXNewExpr *E)
Address getAddress() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ArrayRef< QualType > getParamTypes() const
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
static llvm::Value * EmitTypeidFromVTable(CodeGenFunction &CGF, const Expr *E, llvm::Type *StdTypeInfoPtrTy)
llvm::IntegerType * SizeTy
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
QualType getDestroyedType() const
Retrieve the type being destroyed.
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.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
A metaprogramming class for ensuring that a value will dominate an arbitrary position in a function...
__DEVICE__ int max(int __a, int __b)
bool isReplaceableGlobalAllocationFunction(bool *IsAligned=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
Describes an C or C++ initializer list.
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Optional< Expr * > getArraySize()
FunctionDecl * getOperatorDelete() const
bool isElidable() const
Whether this construction is elidable.
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
CharUnits - This is an opaque type for sizes expressed in character units.
void EmitARCDestroyStrong(Address addr, ARCPreciseLifetime_t precise)
Destroy a __strong variable.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
bool isOne() const
isOne - Test whether the quantity equals one.
Expr * getInitializer()
The initializer of this new-expression.
CharUnits getAlignment() const
Return the alignment of this pointer.
A builtin binary operation expression such as "x + y" or "x <= y".
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
Checking the operand of a dynamic_cast or a typeid expression.
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind...
LangAS getAddressSpace() const
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
const Type * getClass() const
Scope - A scope is a transient data structure that is used while parsing the program.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
param_type_iterator param_type_begin() const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
static void EmitNullBaseClassInitialization(CodeGenFunction &CGF, Address DestPtr, const CXXRecordDecl *Base)
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getCorrespondingMethodInClass(const CXXRecordDecl *RD, bool MayBeBase=false)
Find the method in RD that corresponds to this one.
void begin(CodeGenFunction &CGF)
bool isNegative() const
isNegative - Test whether the quantity is less than zero.
This object can be modified without requiring retains or releases.
Checking the 'this' pointer for a call to a non-static member function.
TypeSourceInfo * getAllocatedTypeSourceInfo() const
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
QualType getTypeAsWritten() const
getTypeAsWritten - Returns the type that this expression is casting to, as written in the source code...
void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest)
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
void addFrom(const CallArgList &other)
Add all the arguments from another CallArgList to this one.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ASTContext & getContext() const
Represents a prototype with parameter type info, e.g.
bool isDynamicClass() const
virtual CharUnits GetArrayCookieSize(const CXXNewExpr *expr)
Returns the extra size required in order to store the array cookie for the given new-expression.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any...
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
NestedNameSpecifier * getQualifier() const
If the member name was qualified, retrieves the nested-name-specifier that precedes the member name...
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
SourceLocation getBeginLoc() const
Get the begin source location.
This represents one expression.
bool isVariadic() const
Whether this function is variadic.
bool isDefaulted() const
Whether this function is defaulted per C++0x.
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.
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.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E)
void pushCallObjectDeleteCleanup(const FunctionDecl *OperatorDelete, llvm::Value *CompletePtr, QualType ElementType)
void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo, 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.
const T * castAs() const
Member-template castAs<specific type>.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
SourceLocation getExprLoc() const LLVM_READONLY
Represents a C++ destructor within a class.
bool isSanitizerChecked() const
unsigned getNumInits() const
bool isArrow() const
Determine whether this pseudo-destructor expression was written using an '->' (otherwise, it used a '.
llvm::PointerType * getType() const
Return the type of the pointer value.
virtual bool EmitBadCastCall(CodeGenFunction &CGF)=0
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
A class for recording the number of arguments that a function signature requires. ...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type...
RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, bool HasQualifier, NestedNameSpecifier *Qualifier, bool IsArrow, const Expr *Base)
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 ...
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 hasInitializer() const
Whether this new-expression has any initializer at all.
QualType getRecordType(const RecordDecl *Decl) const
static void EmitObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType)
Emit the code for deleting a single object.
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
llvm::Value * EmitCastToVoidPtr(llvm::Value *value)
Emit a cast to void* in the appropriate address space.
QualType getTypeOperand(ASTContext &Context) const
Retrieves the type operand of this typeid() expression after various required adjustments (removing r...
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...
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
QualType getDestroyedType() const
Retrieve the type being destroyed.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
GlobalDecl - represents a global declaration.
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
There is no lifetime qualification on this type.
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
Assigning into this object requires the old value to be released and the new value to be retained...
QualType getCanonicalType() const
void initFullExprCleanup()
Set up the last cleanup that was pushed as a conditional full-expression cleanup. ...
llvm::Value * EmitCXXTypeidExpr(const CXXTypeidExpr *E)
Encodes a location in the source.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums...
LangAS getAddressSpace() const
Return the address space of this type.
virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0
A saved depth on the scope stack.
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **callOrInvoke, SourceLocation Loc)
EmitCall - Generate a call of the given function, expecting the given result type, and using the given argument list which specifies both the LLVM arguments and the types they were derived from.
bool shouldNullCheckAllocation() const
True if the allocation result needs to be null-checked.
static CXXRecordDecl * getCXXRecord(const Expr *E)
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Represents a call to a member function that may be written either with member call syntax (e...
const Decl * getDecl() const
A scoped helper to set the current debug location to the specified location or preferred location of ...
static void EmitArrayDelete(CodeGenFunction &CGF, const CXXDeleteExpr *E, Address deletedPtr, QualType elementType)
Emit the code for deleting an array of objects.
Represents a static or instance method of a struct/union/class.
const ConstantArrayType * getAsConstantArrayType(QualType T) const
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
llvm::Constant * EmitNullConstantForBase(const CXXRecordDecl *Record)
Return a null constant appropriate for zero-initializing a base class with the given type...
QualType getAllocatedType() const
virtual void emitVirtualObjectDelete(CodeGenFunction &CGF, const CXXDeleteExpr *DE, Address Ptr, QualType ElementType, const CXXDestructorDecl *Dtor)=0
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
All available information about a concrete callee.
const CXXRecordDecl * getBestDynamicClassType() const
For an expression of class type or pointer to class type, return the most derived class decl the expr...
EnumDecl * getDecl() const
RValue EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue)
Assigning into this object requires a lifetime extension.
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.
bool passAlignment() const
Indicates whether the required alignment should be implicitly passed to the allocation function...
FunctionDecl * getOperatorDelete() const
CXXCtorType
C++ constructor types.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
static CharUnits CalculateCookiePadding(CodeGenFunction &CGF, const CXXNewExpr *E)
CharUnits getNonVirtualAlignment() const
getNonVirtualSize - Get the non-virtual alignment (in chars) of an object, which is the alignment of ...
CGFunctionInfo - Class to encapsulate the information about a function definition.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
bool isTypeOperand() const
Dataflow Directional Tag Classes.
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
Qualifiers getMethodQualifiers() const
bool isInConditionalBranch() const
isInConditionalBranch - Return true if we're currently emitting one branch or the other of a conditio...
The name of a declaration.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined...
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type *> Tys=None)
A pointer to member type per C++ 8.3.3 - Pointers to members.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
llvm::Module & getModule() const
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type. ...
bool isStringLiteralInit() const
static llvm::Value * EmitDynamicCastToNull(CodeGenFunction &CGF, QualType DestTy)
AlignmentSource getAlignmentSource() const
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional)
Compute the arguments required by the given formal prototype, given that there may be some additional...
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
CXXMethodDecl * getDevirtualizedMethod(const Expr *Base, bool IsAppleKext)
If it's possible to devirtualize a call to this method, return the called function.
CodeGenTypes & getTypes() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Represents a call to a CUDA kernel function.
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
Expr * getArg(unsigned Arg)
Return the specified argument.
Base for LValueReferenceType and RValueReferenceType.
void EmitSynthesizedCXXCopyCtor(Address Dest, Address Src, const Expr *Exp)
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.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
bool isConstantArrayType() const
static bool isGLValueFromPointerDeref(const Expr *E)
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Reading or writing from this object requires a barrier call.
QualType getParamType(unsigned i) const
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Represents a C++ struct/union/class.
virtual const CXXRecordDecl * getThisArgumentTypeForMethod(const CXXMethodDecl *MD)
Get the type of the implicit "this" parameter used by a method.
bool hasStrongOrWeakObjCLifetime() const
static void EmitNewInitializer(CodeGenFunction &CGF, const CXXNewExpr *E, QualType ElementType, llvm::Type *ElementTy, Address NewPtr, llvm::Value *NumElements, llvm::Value *AllocSizeWithoutCookie)
llvm::Type * ConvertType(QualType T)
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, const CallExpr *TheCallExpr, bool IsDelete)
void EmitCXXDeleteExpr(const CXXDeleteExpr *E)
LValue EmitLValue(const Expr *E)
EmitLValue - Emit code to compute a designator that specifies the location of the expression...
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
T * pushCleanupWithExtra(CleanupKind Kind, size_t N, As... A)
Push a cleanup with non-constant storage requirements on the stack.
static CGCallee forVirtual(const CallExpr *CE, GlobalDecl MD, Address Addr, llvm::FunctionType *FTy)
static UsualDeleteParams getUsualDeleteParams(const FunctionDecl *FD)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
llvm::Constant * tryEmitAbstract(const Expr *E, QualType T)
Try to emit the result of the given expression as an abstract constant.
CGCXXABI & getCXXABI() const
bool isAlwaysNull() const
isAlwaysNull - Return whether the result of the dynamic_cast is proven to always be null...
static RValue get(llvm::Value *V)
bool isPointerType() const
static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, QualType AllocType, Address NewPtr, AggValueSlot::Overlap_t MayOverlap)
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...
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
virtual std::vector< CharUnits > getVBPtrOffsets(const CXXRecordDecl *RD)
Gets the offsets of all the virtual base pointers in a given class.
LValue - This represents an lvalue references.
An abstract representation of regular/ObjC call/message targets.
Information for lazily generating a cleanup.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isPotentiallyEvaluated() const
Determine whether this typeid has a type operand which is potentially evaluated, per C++11 [expr...
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue)
TranslationUnitDecl * getTranslationUnitDecl()
CallArgList - Type for representing both the value and type of arguments in a call.
void PopCleanupBlock(bool FallThroughIsBranchThrough=false)
PopCleanupBlock - Will pop the cleanup entry on the stack and process all branch fixups.
Represents the canonical version of C arrays with a specified constant size.
Represents an implicitly-generated value initialization of an object of a given type.
QualType getPointeeType() const
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point...
ConstructionKind getConstructionKind() const
Determine whether this constructor is actually constructing a base class (rather than a complete obje...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
param_type_iterator param_type_end() const