22 #include "llvm/IR/CallSite.h" 23 #include "llvm/IR/Intrinsics.h" 25 using namespace clang;
26 using namespace CodeGen;
29 struct MemberCallInfo {
41 assert(CE ==
nullptr || isa<CXXMemberCallExpr>(CE) ||
42 isa<CXXOperatorCallExpr>(CE));
44 "Trying to emit a member or operator call expr on a static method!");
51 RD ? C.getPointerType(C.getTypeDeclType(RD)) : C.VoidPtrTy);
60 unsigned PrefixSize = Args.size() - 1;
70 unsigned ArgsToSkip = isa<CXXOperatorCallExpr>(CE) ? 1 : 0;
76 "No CallExpr specified for function with non-zero number of arguments");
78 return {required, PrefixSize};
89 *
this, MD, This, ImplicitParam, ImplicitParamTy, CE, Args, RtlArgs);
90 auto &FnInfo = CGM.getTypes().arrangeCXXMethodCall(
91 Args, FPT, CallInfo.ReqArgs, CallInfo.PrefixSize);
92 return EmitCall(FnInfo, Callee, ReturnValue, Args,
nullptr,
102 ImplicitParamTy, CE, Args,
nullptr);
103 return EmitCall(CGM.getTypes().arrangeCXXStructorDeclaration(DD, Type),
120 BaseValue = EmitPointerWithAlignment(BaseExpr);
124 LValue BaseLV = EmitLValue(BaseExpr);
137 EmitARCRelease(Builder.CreateLoad(BaseValue,
143 EmitARCDestroyWeak(BaseValue);
163 return cast<CXXRecordDecl>(Ty->
getDecl());
172 if (isa<BinaryOperator>(callee))
173 return EmitCXXMemberPointerCallExpr(CE, ReturnValue);
175 const MemberExpr *ME = cast<MemberExpr>(callee);
178 if (MD->isStatic()) {
181 return EmitCall(getContext().getPointerType(MD->getType()), callee, CE,
190 return EmitCXXMemberOrOperatorMemberCallExpr(
191 CE, MD, ReturnValue, HasQualifier, Qualifier, IsArrow, Base);
198 assert(isa<CXXMemberCallExpr>(CE) || isa<CXXOperatorCallExpr>(CE));
201 bool CanUseVirtualCall = MD->
isVirtual() && !HasQualifier;
204 if (CanUseVirtualCall &&
208 assert(DevirtualizedMethod);
218 DevirtualizedMethod =
nullptr;
228 DevirtualizedMethod =
nullptr;
236 if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(CE)) {
237 if (OCE->isAssignmentOp()) {
238 RtlArgs = &RtlArgStorage;
241 0, EvaluationOrder::ForceRightToLeft);
247 This = EmitPointerWithAlignment(Base);
249 This = EmitLValue(Base).getAddress();
253 if (isa<CXXDestructorDecl>(MD))
return RValue::get(
nullptr);
254 if (isa<CXXConstructorDecl>(MD) &&
255 cast<CXXConstructorDecl>(MD)->isDefaultConstructor())
262 LValue RHS = isa<CXXOperatorCallExpr>(CE)
263 ? MakeNaturalAlignAddrLValue(
264 (*RtlArgs)[0].RV.getScalarVal(),
271 if (isa<CXXConstructorDecl>(MD) &&
272 cast<CXXConstructorDecl>(MD)->isCopyOrMoveConstructor()) {
274 assert(CE->
getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
276 EmitAggregateCopy(This, RHS, (*CE->
arg_begin())->getType());
279 llvm_unreachable(
"unknown trivial member function");
285 DevirtualizedMethod ? DevirtualizedMethod : MD;
287 if (
const auto *Dtor = dyn_cast<CXXDestructorDecl>(CalleeDecl))
288 FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
290 else if (
const auto *Ctor = dyn_cast<CXXConstructorDecl>(CalleeDecl))
291 FInfo = &CGM.getTypes().arrangeCXXStructorDeclaration(
294 FInfo = &CGM.getTypes().arrangeCXXMethodDeclaration(CalleeDecl);
296 llvm::FunctionType *Ty = CGM.getTypes().GetFunctionType(*FInfo);
307 if (
const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
308 auto *IOA = CMCE->getImplicitObjectArgument();
309 bool IsImplicitObjectCXXThis = IsWrappedCXXThis(IOA);
310 if (IsImplicitObjectCXXThis)
311 SkippedChecks.
set(SanitizerKind::Alignment,
true);
312 if (IsImplicitObjectCXXThis || isa<DeclRefExpr>(IOA))
313 SkippedChecks.
set(SanitizerKind::Null,
true);
330 bool UseVirtualCall = CanUseVirtualCall && !DevirtualizedMethod;
334 "Destructor shouldn't have explicit parameters");
335 assert(ReturnValue.
isNull() &&
"Destructor shouldn't have return value");
336 if (UseVirtualCall) {
337 CGM.getCXXABI().EmitVirtualDestructorCall(
338 *
this, Dtor,
Dtor_Complete, This, cast<CXXMemberCallExpr>(CE));
341 if (getLangOpts().AppleKext && MD->
isVirtual() && HasQualifier)
343 else if (!DevirtualizedMethod)
349 cast<CXXDestructorDecl>(DevirtualizedMethod);
354 EmitCXXMemberOrOperatorCall(
355 CalleeDecl, Callee, ReturnValue, This.getPointer(),
366 }
else if (UseVirtualCall) {
367 Callee = CGM.getCXXABI().getVirtualFunctionPointer(*
this, MD, This, Ty,
370 if (SanOpts.has(SanitizerKind::CFINVCall) &&
374 std::tie(VTable, RD) =
375 CGM.getCXXABI().LoadVTablePtr(*
this, This, MD->
getParent());
376 EmitVTablePtrCheckForCall(RD, VTable, CFITCK_NVCall, CE->
getLocStart());
379 if (getLangOpts().AppleKext && MD->
isVirtual() && HasQualifier)
381 else if (!DevirtualizedMethod)
385 CGM.GetAddrOfFunction(DevirtualizedMethod, Ty),
386 DevirtualizedMethod);
391 This = CGM.getCXXABI().adjustThisArgumentForVirtualFunctionCall(
392 *
this, CalleeDecl, This, UseVirtualCall);
395 return EmitCXXMemberOrOperatorCall(
396 CalleeDecl, Callee, ReturnValue, This.getPointer(),
419 This = EmitPointerWithAlignment(BaseExpr);
421 This = EmitLValue(BaseExpr).getAddress();
423 EmitTypeCheck(TCK_MemberCall, E->
getExprLoc(), This.getPointer(),
432 CGM.getCXXABI().EmitLoadOfMemberFunctionPointer(*
this, BO, This,
433 ThisPtrForCall, MemFnPtr, MPT);
438 getContext().getPointerType(getContext().getTagDeclType(RD));
448 return EmitCall(CGM.getTypes().arrangeCXXMethodCall(Args, FPT, required,
450 Callee, ReturnValue, Args,
nullptr, E->
getExprLoc());
458 "Trying to emit a member call expr on a static method!");
459 return EmitCXXMemberOrOperatorMemberCallExpr(
460 E, MD, ReturnValue,
false,
nullptr,
466 return CGM.getCUDARuntime().EmitCUDAKernelCallExpr(*
this, E, ReturnValue);
488 std::vector<CharUnits> VBPtrOffsets =
490 for (
CharUnits VBPtrOffset : VBPtrOffsets) {
492 if (VBPtrOffset >= NVSize)
494 std::pair<CharUnits, CharUnits> LastStore = Stores.pop_back_val();
495 CharUnits LastStoreOffset = LastStore.first;
496 CharUnits LastStoreSize = LastStore.second;
498 CharUnits SplitBeforeOffset = LastStoreOffset;
499 CharUnits SplitBeforeSize = VBPtrOffset - SplitBeforeOffset;
500 assert(!SplitBeforeSize.
isNegative() &&
"negative store size!");
501 if (!SplitBeforeSize.
isZero())
502 Stores.emplace_back(SplitBeforeOffset, SplitBeforeSize);
504 CharUnits SplitAfterOffset = VBPtrOffset + VBPtrWidth;
505 CharUnits SplitAfterSize = LastStoreSize - SplitAfterOffset;
506 assert(!SplitAfterSize.
isNegative() &&
"negative store size!");
507 if (!SplitAfterSize.
isZero())
508 Stores.emplace_back(SplitAfterOffset, SplitAfterSize);
518 if (!NullConstantForBase->isNullValue()) {
519 llvm::GlobalVariable *NullVariable =
new llvm::GlobalVariable(
521 true, llvm::GlobalVariable::PrivateLinkage,
522 NullConstantForBase, Twine());
526 NullVariable->setAlignment(Align.getQuantity());
531 for (std::pair<CharUnits, CharUnits>
Store : Stores) {
545 for (std::pair<CharUnits, CharUnits>
Store : Stores) {
551 CGF.
Builder.getInt8(0), StoreSizeVal);
559 assert(!Dest.
isIgnored() &&
"Must have a destination!");
581 if (CD->isTrivial() && CD->isDefaultConstructor())
587 if (getLangOpts().ElideConstructors && E->
isElidable()) {
588 assert(getContext().hasSameUnqualifiedType(E->
getType(),
591 EmitAggExpr(E->
getArg(0), Dest);
597 = getContext().getAsArrayType(E->
getType())) {
601 bool ForVirtualBase =
false;
602 bool Delegating =
false;
607 Type = CurGD.getCtorType();
616 ForVirtualBase =
true;
624 EmitCXXConstructorCall(CD, Type, ForVirtualBase, Delegating,
632 Exp = E->getSubExpr();
633 assert(isa<CXXConstructExpr>(Exp) &&
634 "EmitSynthesizedCXXCopyCtor - unknown copy ctor expr");
644 EmitNullInitialization(Dest, E->
getType());
646 assert(!getContext().getAsConstantArrayType(E->
getType())
647 &&
"EmitSynthesizedCXXCopyCtor - Copied-in Array");
648 EmitSynthesizedCXXCopyCtorCall(CD, Dest, Src, E);
666 unsigned minElements,
675 return sizeWithoutCookie;
679 unsigned sizeWidth = CGF.
SizeTy->getBitWidth();
682 llvm::APInt cookieSize(sizeWidth,
692 assert(isa<llvm::IntegerType>(numElements->getType()));
702 llvm::IntegerType *numElementsType
703 = cast<llvm::IntegerType>(numElements->getType());
704 unsigned numElementsWidth = numElementsType->getBitWidth();
707 llvm::APInt arraySizeMultiplier(sizeWidth, 1);
710 type = CAT->getElementType();
711 arraySizeMultiplier *= CAT->getSize();
715 llvm::APInt typeSizeMultiplier(sizeWidth, typeSize.
getQuantity());
716 typeSizeMultiplier *= arraySizeMultiplier;
723 if (llvm::ConstantInt *numElementsC =
724 dyn_cast<llvm::ConstantInt>(numElements)) {
725 const llvm::APInt &count = numElementsC->getValue();
727 bool hasAnyOverflow =
false;
730 if (isSigned && count.isNegative())
731 hasAnyOverflow =
true;
736 else if (numElementsWidth > sizeWidth &&
737 numElementsWidth - sizeWidth > count.countLeadingZeros())
738 hasAnyOverflow =
true;
741 llvm::APInt adjustedCount = count.zextOrTrunc(sizeWidth);
745 if (adjustedCount.ult(minElements))
746 hasAnyOverflow =
true;
751 numElements = llvm::ConstantInt::get(CGF.
SizeTy,
752 adjustedCount * arraySizeMultiplier);
756 llvm::APInt allocationSize
757 = adjustedCount.umul_ov(typeSizeMultiplier, overflow);
758 hasAnyOverflow |= overflow;
761 if (cookieSize != 0) {
764 sizeWithoutCookie = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
766 allocationSize = allocationSize.uadd_ov(cookieSize, overflow);
767 hasAnyOverflow |= overflow;
771 if (hasAnyOverflow) {
772 size = llvm::Constant::getAllOnesValue(CGF.
SizeTy);
774 size = llvm::ConstantInt::get(CGF.
SizeTy, allocationSize);
797 if (numElementsWidth > sizeWidth) {
798 llvm::APInt threshold(numElementsWidth, 1);
799 threshold <<= sizeWidth;
802 = llvm::ConstantInt::get(numElementsType, threshold);
804 hasOverflow = CGF.
Builder.CreateICmpUGE(numElements, thresholdV);
805 numElements = CGF.
Builder.CreateTrunc(numElements, CGF.
SizeTy);
808 }
else if (isSigned) {
809 if (numElementsWidth < sizeWidth)
810 numElements = CGF.
Builder.CreateSExt(numElements, CGF.
SizeTy);
817 if (typeSizeMultiplier == 1)
818 hasOverflow = CGF.
Builder.CreateICmpSLT(numElements,
819 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
822 }
else if (numElementsWidth < sizeWidth) {
823 numElements = CGF.
Builder.CreateZExt(numElements, CGF.
SizeTy);
826 assert(numElements->getType() == CGF.
SizeTy);
831 hasOverflow = CGF.
Builder.CreateICmpULT(numElements,
832 llvm::ConstantInt::get(CGF.
SizeTy, minElements));
833 }
else if (numElementsWidth > sizeWidth) {
837 hasOverflow = CGF.
Builder.CreateOr(hasOverflow,
838 CGF.
Builder.CreateICmpULT(numElements,
839 llvm::ConstantInt::get(CGF.
SizeTy, minElements)));
852 if (typeSizeMultiplier != 1) {
857 llvm::ConstantInt::get(CGF.
SizeTy, typeSizeMultiplier);
859 CGF.
Builder.CreateCall(umul_with_overflow, {size, tsmV});
863 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
865 hasOverflow = overflowed;
867 size = CGF.
Builder.CreateExtractValue(result, 0);
870 if (arraySizeMultiplier != 1) {
873 if (typeSize.
isOne()) {
874 assert(arraySizeMultiplier == typeSizeMultiplier);
880 llvm::ConstantInt::get(CGF.
SizeTy, arraySizeMultiplier);
881 numElements = CGF.
Builder.CreateMul(numElements, asmV);
886 assert(arraySizeMultiplier == 1);
890 if (cookieSize != 0) {
891 sizeWithoutCookie = size;
898 CGF.
Builder.CreateCall(uadd_with_overflow, {size, cookieSizeV});
902 hasOverflow = CGF.
Builder.CreateOr(hasOverflow, overflowed);
904 hasOverflow = overflowed;
906 size = CGF.
Builder.CreateExtractValue(result, 0);
913 size = CGF.
Builder.CreateSelect(hasOverflow,
914 llvm::Constant::getAllOnesValue(CGF.
SizeTy),
919 sizeWithoutCookie = size;
921 assert(sizeWithoutCookie &&
"didn't set sizeWithoutCookie?");
948 llvm_unreachable(
"bad evaluation kind");
962 unsigned InitListElements = 0;
968 llvm::Instruction *CleanupDominator =
nullptr;
970 CharUnits ElementSize = getContext().getTypeSizeInChars(ElementType);
975 auto TryMemsetInitialization = [&]() ->
bool {
978 if (!CGM.getTypes().isZeroInitializable(ElementType))
985 auto *RemainingSize = AllocSizeWithoutCookie;
986 if (InitListElements) {
988 auto *InitializedSize = llvm::ConstantInt::get(
989 RemainingSize->getType(),
990 getContext().getTypeSizeInChars(ElementType).getQuantity() *
992 RemainingSize = Builder.CreateSub(RemainingSize, InitializedSize);
996 Builder.CreateMemSet(CurPtr, Builder.getInt8(0), RemainingSize,
false);
1001 if (
const InitListExpr *ILE = dyn_cast<InitListExpr>(Init)) {
1004 if (ILE->isStringLiteralInit()) {
1013 EmitAggExpr(ILE->getInit(0), Slot);
1017 cast<ConstantArrayType>(ILE->getType()->getAsArrayTypeUnsafe())
1018 ->getSize().getZExtValue();
1021 Builder.getSize(InitListElements),
1027 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1028 if (!ConstNum || !ConstNum->equalsInt(InitListElements)) {
1029 bool OK = TryMemsetInitialization();
1031 assert(OK &&
"couldn't memset character type?");
1036 InitListElements = ILE->getNumInits();
1043 ElementTy = ConvertTypeForMem(AllocType);
1044 CurPtr = Builder.CreateElementBitCast(CurPtr, ElementTy);
1045 InitListElements *= getContext().getConstantArrayElementCount(CAT);
1049 if (needsEHCleanup(DtorKind)) {
1054 EndOfInit = CreateTempAlloca(BeginPtr.
getType(), getPointerAlign(),
1056 CleanupDominator = Builder.CreateStore(BeginPtr.
getPointer(), EndOfInit);
1057 pushIrregularPartialArrayCleanup(BeginPtr.
getPointer(), EndOfInit,
1058 ElementType, ElementAlign,
1059 getDestroyer(DtorKind));
1060 Cleanup = EHStack.stable_begin();
1064 for (
unsigned i = 0, e = ILE->getNumInits(); i != e; ++i) {
1071 Builder.CreateStore(FinishedPtr, EndOfInit);
1077 ILE->getInit(i)->getType(), CurPtr);
1078 CurPtr =
Address(Builder.CreateInBoundsGEP(CurPtr.getPointer(),
1085 Init = ILE->getArrayFiller();
1090 while (Init && Init->
getType()->isConstantArrayType()) {
1094 assert(SubILE->getNumInits() == 0 &&
"explicit inits in array filler?");
1095 Init = SubILE->getArrayFiller();
1099 CurPtr = Builder.CreateBitCast(CurPtr, BeginPtr.
getType());
1104 llvm::ConstantInt *ConstNum = dyn_cast<llvm::ConstantInt>(NumElements);
1105 if (ConstNum && ConstNum->getZExtValue() <= InitListElements) {
1107 if (CleanupDominator)
1108 DeactivateCleanupBlock(Cleanup, CleanupDominator);
1112 assert(Init &&
"have trailing elements to initialize but no initializer");
1124 if (TryMemsetInitialization())
1133 Builder.CreateStore(CurPtr.
getPointer(), EndOfInit);
1136 if (InitListElements)
1137 NumElements = Builder.CreateSub(
1139 llvm::ConstantInt::get(NumElements->getType(), InitListElements));
1140 EmitCXXAggrConstructorCall(Ctor, NumElements, CurPtr, CCE,
1141 CCE->requiresZeroInitialization());
1147 if (isa<ImplicitValueInitExpr>(Init)) {
1148 if (TryMemsetInitialization())
1159 assert(getContext().hasSameUnqualifiedType(ElementType, Init->
getType()) &&
1160 "got wrong type of element to initialize");
1163 if (
auto *ILE = dyn_cast<InitListExpr>(Init))
1164 if (ILE->getNumInits() == 0 && TryMemsetInitialization())
1169 if (
auto *ILE = dyn_cast<InitListExpr>(Init)) {
1171 if (RType->getDecl()->isStruct()) {
1172 unsigned NumElements = 0;
1173 if (
auto *CXXRD = dyn_cast<CXXRecordDecl>(RType->getDecl()))
1174 NumElements = CXXRD->getNumBases();
1175 for (
auto *Field : RType->getDecl()->fields())
1176 if (!Field->isUnnamedBitfield())
1179 if (ILE->getNumInits() == NumElements)
1180 for (
unsigned i = 0, e = ILE->getNumInits(); i != e; ++i)
1181 if (!isa<ImplicitValueInitExpr>(ILE->getInit(i)))
1183 if (ILE->getNumInits() == NumElements && TryMemsetInitialization())
1190 llvm::BasicBlock *EntryBB = Builder.GetInsertBlock();
1191 llvm::BasicBlock *LoopBB = createBasicBlock(
"new.loop");
1192 llvm::BasicBlock *ContBB = createBasicBlock(
"new.loop.end");
1196 Builder.CreateInBoundsGEP(BeginPtr.
getPointer(), NumElements,
"array.end");
1202 Builder.CreateICmpEQ(CurPtr.
getPointer(), EndPtr,
"array.isempty");
1203 Builder.CreateCondBr(IsEmpty, ContBB, LoopBB);
1210 llvm::PHINode *CurPtrPhi =
1211 Builder.CreatePHI(CurPtr.
getType(), 2,
"array.cur");
1212 CurPtrPhi->addIncoming(CurPtr.
getPointer(), EntryBB);
1214 CurPtr =
Address(CurPtrPhi, ElementAlign);
1218 Builder.CreateStore(CurPtr.
getPointer(), EndOfInit);
1221 if (!CleanupDominator && needsEHCleanup(DtorKind)) {
1223 ElementType, ElementAlign,
1224 getDestroyer(DtorKind));
1225 Cleanup = EHStack.stable_begin();
1226 CleanupDominator = Builder.CreateUnreachable();
1233 if (CleanupDominator) {
1234 DeactivateCleanupBlock(Cleanup, CleanupDominator);
1235 CleanupDominator->eraseFromParent();
1240 Builder.CreateConstInBoundsGEP1_32(ElementTy, CurPtr.
getPointer(), 1,
1245 llvm::Value *IsEnd = Builder.CreateICmpEQ(NextPtr, EndPtr,
"array.atend");
1246 Builder.CreateCondBr(IsEnd, ContBB, LoopBB);
1247 CurPtrPhi->addIncoming(NextPtr, Builder.GetInsertBlock());
1259 AllocSizeWithoutCookie);
1270 llvm::Instruction *CallOrInvoke;
1275 Args, CalleeType,
false),
1283 llvm::Function *Fn = dyn_cast<llvm::Function>(CalleePtr);
1285 Fn && Fn->hasFnAttribute(llvm::Attribute::NoBuiltin)) {
1287 if (llvm::CallInst *CI = dyn_cast<llvm::CallInst>(CallOrInvoke))
1288 CI->addAttribute(llvm::AttributeList::FunctionIndex,
1289 llvm::Attribute::Builtin);
1290 else if (llvm::InvokeInst *II = dyn_cast<llvm::InvokeInst>(CallOrInvoke))
1291 II->addAttribute(llvm::AttributeList::FunctionIndex,
1292 llvm::Attribute::Builtin);
1294 llvm_unreachable(
"unexpected kind of call instruction");
1304 const Stmt *ArgS = Arg;
1309 .getCXXOperatorName(IsDelete ? OO_Delete : OO_New);
1311 if (
auto *FD = dyn_cast<FunctionDecl>(
Decl))
1312 if (Ctx.hasSameType(FD->getType(),
QualType(Type, 0)))
1314 llvm_unreachable(
"predeclared global operator new/delete is missing");
1319 struct UsualDeleteParams {
1320 bool DestroyingDelete =
false;
1322 bool Alignment =
false;
1327 UsualDeleteParams Params;
1337 Params.DestroyingDelete =
true;
1349 Params.Alignment =
true;
1353 assert(AI == AE &&
"unexpected usual deallocation function parameter");
1361 template<
typename Traits>
1364 typedef typename Traits::ValueTy ValueTy;
1366 typedef typename Traits::RValueTy RValueTy;
1367 struct PlacementArg {
1372 unsigned NumPlacementArgs : 31;
1373 unsigned PassAlignmentToPlacementDelete : 1;
1379 PlacementArg *getPlacementArgs() {
1380 return reinterpret_cast<PlacementArg *
>(
this + 1);
1384 static size_t getExtraSize(
size_t NumPlacementArgs) {
1385 return NumPlacementArgs *
sizeof(PlacementArg);
1388 CallDeleteDuringNew(
size_t NumPlacementArgs,
1390 ValueTy AllocSize,
bool PassAlignmentToPlacementDelete,
1392 : NumPlacementArgs(NumPlacementArgs),
1393 PassAlignmentToPlacementDelete(PassAlignmentToPlacementDelete),
1394 OperatorDelete(OperatorDelete), Ptr(Ptr), AllocSize(AllocSize),
1395 AllocAlign(AllocAlign) {}
1397 void setPlacementArg(
unsigned I, RValueTy Arg,
QualType Type) {
1398 assert(I < NumPlacementArgs &&
"index out of range");
1399 getPlacementArgs()[I] = {Arg, Type};
1412 UsualDeleteParams Params;
1413 if (NumPlacementArgs) {
1416 Params.Alignment = PassAlignmentToPlacementDelete;
1423 assert(!Params.DestroyingDelete &&
1424 "should not call destroying delete in a new-expression");
1428 DeleteArgs.add(Traits::get(CGF, AllocSize),
1435 if (Params.Alignment)
1436 DeleteArgs.add(
RValue::get(llvm::ConstantInt::get(
1441 for (
unsigned I = 0; I != NumPlacementArgs; ++I) {
1442 auto Arg = getPlacementArgs()[I];
1443 DeleteArgs.add(Traits::get(CGF, Arg.ArgValue), Arg.ArgType);
1465 struct DirectCleanupTraits {
1469 static RValue get(CodeGenFunction &, RValueTy V) {
return V; }
1472 typedef CallDeleteDuringNew<DirectCleanupTraits> DirectCleanup;
1474 DirectCleanup *Cleanup = CGF.
EHStack 1483 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1484 Cleanup->setPlacementArg(I, Arg.RV, Arg.Ty);
1496 struct ConditionalCleanupTraits {
1500 return V.restore(CGF);
1503 typedef CallDeleteDuringNew<ConditionalCleanupTraits> ConditionalCleanup;
1505 ConditionalCleanup *Cleanup = CGF.
EHStack 1514 auto &Arg = NewArgs[I + NumNonPlacementArgs];
1530 unsigned minElements = 0;
1536 ->getSize().getZExtValue();
1545 allocSizeWithoutCookie);
1546 CharUnits allocAlign = getContext().getTypeAlignInChars(allocType);
1557 allocation = EmitPointerWithAlignment(arg, &BaseInfo);
1569 allocatorArgs.
add(
RValue::get(allocSize), getContext().getSizeType());
1576 unsigned ParamsToSkip = 0;
1579 QualType sizeType = getContext().getSizeType();
1583 if (allocSize != allocSizeWithoutCookie) {
1585 allocAlign =
std::max(allocAlign, cookieAlign);
1593 assert(getContext().hasSameUnqualifiedType(
1596 "wrong type for alignment parameter");
1600 assert(allocator->
isVariadic() &&
"can't pass alignment to allocator");
1621 unsigned AllocatorAlign = llvm::PowerOf2Floor(std::min<uint64_t>(
1622 Target.getNewAlign(), getContext().getTypeSize(allocType)));
1624 allocationAlign, getContext().toCharUnitsFromBits(AllocatorAlign));
1627 allocation =
Address(RV.getScalarVal(), allocationAlign);
1637 llvm::BasicBlock *nullCheckBB =
nullptr;
1638 llvm::BasicBlock *contBB =
nullptr;
1645 conditional.
begin(*
this);
1647 nullCheckBB = Builder.GetInsertBlock();
1648 llvm::BasicBlock *notNullBB = createBasicBlock(
"new.notnull");
1649 contBB = createBasicBlock(
"new.cont");
1652 Builder.CreateIsNull(allocation.
getPointer(),
"new.isnull");
1653 Builder.CreateCondBr(isNull, contBB, notNullBB);
1654 EmitBlock(notNullBB);
1660 llvm::Instruction *cleanupDominator =
nullptr;
1665 operatorDeleteCleanup = EHStack.stable_begin();
1666 cleanupDominator = Builder.CreateUnreachable();
1669 assert((allocSize == allocSizeWithoutCookie) ==
1671 if (allocSize != allocSizeWithoutCookie) {
1673 allocation = CGM.getCXXABI().InitializeArrayCookie(*
this, allocation,
1678 llvm::Type *elementTy = ConvertTypeForMem(allocType);
1679 Address result = Builder.CreateElementBitCast(allocation, elementTy);
1685 if (CGM.getCodeGenOpts().StrictVTablePointers &&
1691 allocSizeWithoutCookie);
1697 if (result.
getType() != resultType)
1698 result = Builder.CreateBitCast(result, resultType);
1703 if (operatorDeleteCleanup.
isValid()) {
1704 DeactivateCleanupBlock(operatorDeleteCleanup, cleanupDominator);
1705 cleanupDominator->eraseFromParent();
1710 conditional.
end(*
this);
1712 llvm::BasicBlock *notNullBB = Builder.GetInsertBlock();
1715 llvm::PHINode *PHI = Builder.CreatePHI(resultPtr->getType(), 2);
1716 PHI->addIncoming(resultPtr, notNullBB);
1717 PHI->addIncoming(llvm::Constant::getNullValue(resultPtr->getType()),
1730 assert((!NumElements && CookieSize.
isZero()) ||
1739 auto ParamTypeIt = DeleteFTy->param_type_begin();
1743 llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
1747 if (Params.DestroyingDelete) {
1750 auto *V = llvm::UndefValue::get(getTypes().ConvertType(DDTag));
1756 QualType SizeType = *ParamTypeIt++;
1757 CharUnits DeleteTypeSize = getContext().getTypeSizeInChars(DeleteTy);
1758 llvm::Value *Size = llvm::ConstantInt::get(ConvertType(SizeType),
1763 Size = Builder.CreateMul(Size, NumElements);
1766 if (!CookieSize.
isZero())
1767 Size = Builder.CreateAdd(
1768 Size, llvm::ConstantInt::get(SizeTy, CookieSize.
getQuantity()));
1774 if (Params.Alignment) {
1775 QualType AlignValType = *ParamTypeIt++;
1776 CharUnits DeleteTypeAlign = getContext().toCharUnitsFromBits(
1777 getContext().getTypeAlignIfKnown(DeleteTy));
1778 llvm::Value *Align = llvm::ConstantInt::get(ConvertType(AlignValType),
1783 assert(ParamTypeIt == DeleteFTy->param_type_end() &&
1784 "unknown parameter to usual delete function");
1800 : Ptr(Ptr), OperatorDelete(OperatorDelete), ElementType(ElementType) {}
1813 OperatorDelete, ElementType);
1824 if (Dtor && Dtor->isVirtual())
1856 if (Dtor->isVirtual()) {
1869 OperatorDelete, ElementType);
1910 : Ptr(Ptr), OperatorDelete(OperatorDelete), NumElements(NumElements),
1911 ElementType(ElementType), CookieSize(CookieSize) {}
1914 CGF.
EmitDeleteCall(OperatorDelete, Ptr, ElementType, NumElements,
1929 numElements, allocatedPtr, cookieSize);
1931 assert(allocatedPtr &&
"ReadArrayCookie didn't set allocated pointer");
1936 allocatedPtr, operatorDelete,
1937 numElements, elementType,
1942 assert(numElements &&
"no element count for a type with a destructor!");
1950 CGF.
Builder.CreateInBoundsGEP(arrayBegin, numElements,
"delete.end");
1967 Address Ptr = EmitPointerWithAlignment(Arg);
1970 llvm::BasicBlock *DeleteNotNull = createBasicBlock(
"delete.notnull");
1971 llvm::BasicBlock *DeleteEnd = createBasicBlock(
"delete.end");
1975 Builder.CreateCondBr(IsNull, DeleteEnd, DeleteNotNull);
1976 EmitBlock(DeleteNotNull);
1984 EmitBlock(DeleteEnd);
1995 GEP.push_back(Zero);
1999 = getContext().getAsConstantArrayType(DeleteTy)) {
2001 DeleteTy = Arr->getElementType();
2004 GEP.push_back(Zero);
2019 EmitBlock(DeleteEnd);
2025 if (
const auto *CE = dyn_cast<CastExpr>(E)) {
2026 if (!CE->getSubExpr()->isGLValue())
2031 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
2034 if (
const auto *BO = dyn_cast<BinaryOperator>(E))
2035 if (BO->getOpcode() == BO_Comma)
2038 if (
const auto *ACO = dyn_cast<AbstractConditionalOperator>(E))
2044 if (isa<ArraySubscriptExpr>(E))
2047 if (
const auto *UO = dyn_cast<UnaryOperator>(E))
2048 if (UO->getOpcode() == UO_Deref)
2078 llvm::BasicBlock *BadTypeidBlock =
2083 CGF.
Builder.CreateCondBr(IsNull, BadTypeidBlock, EndBlock);
2096 ConvertType(E->
getType())->getPointerTo();
2101 return Builder.CreateBitCast(TypeInfo, StdTypeInfoPtrTy);
2114 return Builder.CreateBitCast(CGM.GetAddrOfRTTIDescriptor(OperandTy),
2122 return llvm::Constant::getNullValue(DestLTy);
2130 return llvm::UndefValue::get(DestLTy);
2135 CGM.EmitExplicitCastExprType(DCE,
this);
2145 bool isDynamicCastToVoid;
2153 isDynamicCastToVoid =
false;
2154 SrcRecordTy = SrcTy;
2170 assert(SrcRecordTy->
isRecordType() &&
"source type must be a record type!");
2175 bool ShouldNullCheckSrcValue =
2176 CGM.getCXXABI().shouldDynamicCastCallBeNullChecked(SrcTy->
isPointerType(),
2179 llvm::BasicBlock *CastNull =
nullptr;
2180 llvm::BasicBlock *CastNotNull =
nullptr;
2181 llvm::BasicBlock *CastEnd = createBasicBlock(
"dynamic_cast.end");
2183 if (ShouldNullCheckSrcValue) {
2184 CastNull = createBasicBlock(
"dynamic_cast.null");
2185 CastNotNull = createBasicBlock(
"dynamic_cast.notnull");
2188 Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
2189 EmitBlock(CastNotNull);
2193 if (isDynamicCastToVoid) {
2194 Value = CGM.getCXXABI().EmitDynamicCastToVoid(*
this, ThisAddr, SrcRecordTy,
2198 "destination type must be a record type!");
2199 Value = CGM.getCXXABI().EmitDynamicCastCall(*
this, ThisAddr, SrcRecordTy,
2200 DestTy, DestRecordTy, CastEnd);
2201 CastNotNull = Builder.GetInsertBlock();
2204 if (ShouldNullCheckSrcValue) {
2205 EmitBranch(CastEnd);
2207 EmitBlock(CastNull);
2208 EmitBranch(CastEnd);
2213 if (ShouldNullCheckSrcValue) {
2214 llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2);
2215 PHI->addIncoming(Value, CastNotNull);
2216 PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull);
2231 i != e; ++i, ++CurField) {
2233 LValue LV = EmitLValueForFieldInitialization(SlotLV, *CurField);
2234 if (CurField->hasCapturedVLAType()) {
2235 auto VAT = CurField->getCapturedVLAType();
2236 EmitStoreThroughLValue(
RValue::get(VLASizeMap[VAT->getSizeExpr()]), LV);
2238 EmitInitializerForField(*CurField, LV, *i);
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
An instance of this class is created to represent 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...
Stmt - This represents one statement.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
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
Checking the 'this' pointer for a constructor call.
bool isRecordType() const
Decl - This represents one declaration (or definition), e.g.
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, QualType Type, CharUnits Alignment=CharUnits::Zero(), SanitizerSet SkippedChecks=SanitizerSet())
Emit a check that V is the address of storage of the appropriate size and alignment for an object of ...
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 ...
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
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
Ignore parentheses and derived-to-base casts.
static llvm::Value * EmitCXXNewAllocSize(CodeGenFunction &CGF, const CXXNewExpr *e, unsigned minElements, llvm::Value *&numElements, llvm::Value *&sizeWithoutCookie)
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::Instruction **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.
static saved_type save(CodeGenFunction &CGF, type value)
QualType getReturnType() const
unsigned getNumParams() const
const T * getAs() const
Member-template getAs<specific type>'.
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.
CXXRecordDecl * getLambdaClass() const
Retrieve the class that corresponds to the lambda.
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 ...
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 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...
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...
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...
capture_init_iterator capture_init_begin()
Retrieve the first initialization argument for this lambda expression (which initializes the first ca...
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...
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.
static void StoreAnyExprIntoOneUnit(CodeGenFunction &CGF, const Expr *Init, QualType AllocType, Address NewPtr)
void initFullExprCleanup()
Set up the last cleaup that was pushed as a conditional full-expression cleanup.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
field_iterator field_begin() const
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)
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
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.
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.
Expr - 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...
const FunctionProtoType * T
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.
unsigned getNumInits() const
const Expr * getCallee() 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
void add(RValue rvalue, QualType type, bool needscopy=false)
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...
void EmitLambdaExpr(const LambdaExpr *E, AggValueSlot Dest)
RValue EmitCXXMemberOrOperatorMemberCallExpr(const CallExpr *CE, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, bool HasQualifier, NestedNameSpecifier *Qualifier, bool IsArrow, const Expr *Base)
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.
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
forAddr - Make a slot for an aggregate value.
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
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...
virtual llvm::Value * EmitTypeid(CodeGenFunction &CGF, QualType SrcRecordTy, Address ThisPtr, llvm::Type *StdTypeInfoPtrTy)=0
A saved depth on the scope stack.
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...
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
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
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.
RValue EmitBuiltinNewDeleteCall(const FunctionProtoType *Type, const Expr *Arg, bool IsDelete)
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.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This)
Represents a delete expression for memory deallocation and destructor calls, e.g. ...
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
bool isInConditionalBranch() const
isInConditionalBranch - Return true if we're currently emitting one branch or the other of a conditio...
DeclarationName - The name of a declaration.
const CXXRecordDecl * getParent() const
Returns 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)
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
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
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.
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.
SourceLocation getLocStart() const LLVM_READONLY
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
char __ovld __cnfn max(char x, char y)
Returns y if x < y, otherwise it returns x.
static bool isGLValueFromPointerDeref(const Expr *E)
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
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.
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 UsualDeleteParams getUsualDeleteParams(const FunctionDecl *FD)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
QualType getIntegerType() const
getIntegerType - 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
capture_init_iterator capture_init_end()
Retrieve the iterator pointing one past the last initialization argument for this lambda expression...
bool isAlwaysNull() const
isAlwaysNull - Return whether the result of the dynamic_cast is proven to always be null...
static RValue get(llvm::Value *V)
static RequiredArgs forPrototypePlus(const FunctionProtoType *prototype, unsigned additional, const FunctionDecl *FD)
Compute the arguments required by the given formal prototype, given that there may be some additional...
Expr *const * const_capture_init_iterator
Const iterator that walks over the capture initialization arguments.
bool isPointerType() const
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.
bool shouldNullCheckAllocation(const ASTContext &Ctx) const
True if the allocation result needs to be null-checked.
LValue - This represents an lvalue references.
An abstract representation of regular/ObjC call/message targets.
Information for lazily generating a cleanup.
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
IgnoreParens - Ignore parentheses.
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