30#include "llvm/IR/Intrinsics.h"
31#include "llvm/IR/Metadata.h"
32#include "llvm/Support/SaveAndRestore.h"
33#include "llvm/Transforms/Utils/ModuleUtils.h"
34#include "llvm/Transforms/Utils/SanitizerStats.h"
54 return layout.getNonVirtualAlignment();
86 CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
99 return std::min(actualBaseAlign, expectedTargetAlign);
102 CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
122 if (actualBaseAlign >= expectedBaseAlign) {
123 return expectedTargetAlign;
129 return std::min(actualBaseAlign, expectedTargetAlign);
133 assert(
CurFuncDecl &&
"loading 'this' without a func declaration?");
137 if (CXXThisAlignment.isZero()) {
141 CXXThisAlignment =
CGM.getClassPointerAlignment(MD->getParent());
145 LoadCXXThis(), MD->getFunctionObjectParameterType(), CXXThisAlignment,
153 const Expr *E,
Address base, llvm::Value *memberPtr,
157 llvm::Value *ptr =
CGM.getCXXABI().EmitMemberDataPointerAddress(
158 *
this, E, base, memberPtr, memberPtrType, IsInBounds);
162 CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo);
163 memberAlign =
CGM.getDynamicOffsetAlignment(
180 assert(!
Base->isVirtual() &&
"Should not see virtual bases here!");
185 const auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
198 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
208 return llvm::ConstantInt::get(
PtrDiffTy, Offset.getQuantity());
218 bool BaseIsVirtual) {
233 if (!Offset.isZero()) {
235 V =
Builder.CreateConstInBoundsByteGEP(
V, Offset);
242 llvm::Value *virtualOffset,
const CXXRecordDecl *derivedClass,
245 assert(!nonVirtualOffset.
isZero() || virtualOffset !=
nullptr);
248 llvm::Value *baseOffset;
249 if (!nonVirtualOffset.
isZero()) {
250 llvm::Type *OffsetType =
256 llvm::ConstantInt::get(OffsetType, nonVirtualOffset.
getQuantity());
258 baseOffset = CGF.
Builder.CreateAdd(virtualOffset, baseOffset);
261 baseOffset = virtualOffset;
272 assert(nearestVBase &&
"virtual offset without vbase?");
288 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
297 if ((*Start)->isVirtual()) {
298 VBase = (*Start)->getType()->castAsCXXRecordDecl();
305 CharUnits NonVirtualOffset =
CGM.computeNonVirtualBaseClassOffset(
306 VBase ? VBase : Derived, Start, PathEnd);
311 if (VBase && Derived->
hasAttr<FinalAttr>()) {
314 NonVirtualOffset += vBaseOffset;
320 llvm::Type *PtrTy = llvm::PointerType::get(
324 CharUnits DerivedAlign =
CGM.getClassPointerAlignment(Derived);
328 if (NonVirtualOffset.
isZero() && !VBase) {
331 SkippedChecks.
set(SanitizerKind::Null, !NullCheckValue);
333 DerivedAlign, SkippedChecks);
335 return Value.withElementType(BaseValueTy);
338 llvm::BasicBlock *origBB =
nullptr;
339 llvm::BasicBlock *endBB =
nullptr;
343 if (NullCheckValue) {
344 origBB =
Builder.GetInsertBlock();
349 Builder.CreateCondBr(isNull, endBB, notNullBB);
355 SkippedChecks.
set(SanitizerKind::Null,
true);
357 Value.emitRawPointer(*
this), DerivedTy, DerivedAlign,
362 llvm::Value *VirtualOffset =
nullptr;
365 CGM.getCXXABI().GetVirtualBaseClassOffset(*
this,
Value, Derived, VBase);
370 VirtualOffset, Derived, VBase);
376 if (NullCheckValue) {
377 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
381 llvm::PHINode *PHI =
Builder.CreatePHI(PtrTy, 2,
"cast.result");
382 PHI->addIncoming(
Value.emitRawPointer(*
this), notNullBB);
383 PHI->addIncoming(llvm::Constant::getNullValue(PtrTy), origBB);
394 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
397 llvm::Type *DerivedValueTy =
ConvertType(DerivedTy);
399 llvm::Value *NonVirtualOffset =
400 CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd);
402 if (!NonVirtualOffset) {
407 llvm::BasicBlock *CastNull =
nullptr;
408 llvm::BasicBlock *CastNotNull =
nullptr;
409 llvm::BasicBlock *CastEnd =
nullptr;
411 if (NullCheckValue) {
425 CGM.getClassPointerAlignment(Derived),
"sub.ptr");
428 Addr =
Addr.withElementType(DerivedValueTy);
431 if (NullCheckValue) {
437 llvm::Value *
Value =
Addr.emitRawPointer(*
this);
439 PHI->addIncoming(
Value, CastNotNull);
440 PHI->addIncoming(llvm::Constant::getNullValue(
Value->
getType()), CastNull);
442 CGM.getClassPointerAlignment(Derived));
451 if (!
CGM.getCXXABI().NeedsVTTParameter(GD)) {
459 uint64_t SubVTTIndex;
464 }
else if (RD ==
Base) {
467 assert(!
CGM.getCXXABI().NeedsVTTParameter(
CurGD) &&
468 "doing no-op VTT offset in base dtor/ctor?");
469 assert(!ForVirtualBase &&
"Can't have same class as virtual base!");
478 assert(SubVTTIndex != 0 &&
"Sub-VTT index must be greater than zero!");
482 if (
CGM.getCXXABI().NeedsVTTParameter(
CurGD)) {
487 VTT =
CGM.getVTables().GetAddrOfVTT(RD);
489 return Builder.CreateConstInBoundsGEP1_64(
CGM.GlobalsInt8PtrTy, VTT,
495struct CallBaseDtor final : EHScopeStack::Cleanup {
499 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
512 false,
Addr, ThisTy);
539 ThisPtr, ClassDecl, BaseClassDecl, isBaseVirtual);
548 !BaseClassDecl->hasTrivialDestructor())
560 for (
const auto *I : IndirectField->
chain())
575 "Must have member initializer!");
576 assert(MemberInit->
getInit() &&
"Must have initializer!");
580 QualType FieldType = Field->getType();
609 unsigned SrcArgIndex =
611 llvm::Value *SrcPtr =
619 LHS.isVolatileQualified());
634 QualType FieldType = Field->getType();
726 struct SizeAndOffset {
731 unsigned PtrSize =
CGM.getDataLayout().getPointerSizeInBits();
738 Context.toCharUnitsFromBits(Info.
getFieldOffset(i)).getQuantity();
740 size_t NumFields = 0;
741 for (
const auto *Field : ClassDecl->
fields()) {
743 auto FieldInfo = Context.getTypeInfoInChars(D->
getType());
745 assert(NumFields < SSV.size());
749 assert(NumFields == SSV.size());
756 llvm::FunctionType *FTy = llvm::FunctionType::get(
CGM.VoidTy, Args,
false);
757 llvm::FunctionCallee F =
CGM.CreateRuntimeFunction(
758 FTy, Prologue ?
"__asan_poison_intra_object_redzone"
759 :
"__asan_unpoison_intra_object_redzone");
766 for (
size_t i = 0; i < SSV.size(); i++) {
767 uint64_t AsanAlignment = 8;
768 uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
769 uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
770 uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
771 if (PoisonSize < AsanAlignment || !SSV[i].Size ||
772 (NextField % AsanAlignment) != 0)
775 F, {
Builder.CreateAdd(ThisPtr,
Builder.getIntN(PtrSize, EndOffset)),
776 Builder.getIntN(PtrSize, PoisonSize)});
786 assert((
CGM.getTarget().getCXXABI().hasConstructorVariants() ||
788 "can only generate complete ctor for this ABI");
793 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
800 assert(
Definition == Ctor &&
"emitting wrong constructor body");
804 bool IsTryBody = isa_and_nonnull<CXXTryStmt>(Body);
841class CopyingValueRepresentation {
844 : CGF(CGF), OldSanOpts(CGF.SanOpts) {
848 ~CopyingValueRepresentation() { CGF.
SanOpts = OldSanOpts; }
857class FieldMemcpyizer {
859 FieldMemcpyizer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
860 const VarDecl *SrcRec)
861 : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
862 RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
864 LastFieldOffset(0), LastAddedFieldIndex(0) {}
866 bool isMemcpyableField(FieldDecl *F)
const {
884 void addMemcpyableField(FieldDecl *F) {
893 CharUnits getMemcpySize(uint64_t FirstByteOffset)
const {
895 unsigned LastFieldSize =
896 LastField->isBitField()
897 ? LastField->getBitWidthValue()
900 uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize -
920 if (FirstField->isBitField()) {
921 const CGRecordLayout &RL =
928 FirstByteOffset = FirstFieldOffset;
931 CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
940 emitMemcpyIR(Dest.isBitField() ? Dest.getBitFieldAddress()
942 Src.isBitField() ? Src.getBitFieldAddress() : Src.getAddress(),
947 void reset() { FirstField =
nullptr; }
950 CodeGenFunction &CGF;
951 const CXXRecordDecl *ClassDecl;
954 void emitMemcpyIR(Address DestPtr, Address SrcPtr, CharUnits Size) {
961 void addInitialField(FieldDecl *F) {
964 FirstFieldOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
965 LastFieldOffset = FirstFieldOffset;
969 void addNextField(FieldDecl *F) {
975 "Cannot aggregate fields out of order.");
982 if (FOffset < FirstFieldOffset) {
984 FirstFieldOffset = FOffset;
985 }
else if (FOffset >= LastFieldOffset) {
987 LastFieldOffset = FOffset;
991 const VarDecl *SrcRec;
992 const ASTRecordLayout &RecLayout;
993 FieldDecl *FirstField;
994 FieldDecl *LastField;
995 uint64_t FirstFieldOffset, LastFieldOffset;
996 unsigned LastAddedFieldIndex;
999class ConstructorMemcpyizer :
public FieldMemcpyizer {
1003 static const VarDecl *getTrivialCopySource(CodeGenFunction &CGF,
1004 const CXXConstructorDecl *CD,
1005 FunctionArgList &Args) {
1013 bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit)
const {
1014 if (!MemcpyableCtor)
1017 assert(Field &&
"No field for member init.");
1018 QualType FieldType =
Field->getType();
1019 CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->
getInit());
1029 if (!isMemcpyableField(Field))
1037 ConstructorMemcpyizer(CodeGenFunction &CGF,
const CXXConstructorDecl *CD,
1038 FunctionArgList &Args)
1039 : FieldMemcpyizer(CGF, CD->getParent(),
1040 getTrivialCopySource(CGF, CD, Args)),
1041 ConstructorDecl(CD),
1042 MemcpyableCtor(CD->isDefaulted() && CD->isCopyOrMoveConstructor() &&
1043 CGF.getLangOpts().getGC() == LangOptions::NonGC),
1046 void addMemberInitializer(CXXCtorInitializer *MemberInit) {
1047 if (isMemberInitMemcpyable(MemberInit)) {
1048 AggregatedInits.push_back(MemberInit);
1049 addMemcpyableField(MemberInit->
getMember());
1051 emitAggregatedInits();
1053 ConstructorDecl, Args);
1057 void emitAggregatedInits() {
1058 if (AggregatedInits.size() <= 1) {
1061 if (!AggregatedInits.empty()) {
1062 CopyingValueRepresentation CVR(CGF);
1064 AggregatedInits[0], ConstructorDecl, Args);
1065 AggregatedInits.clear();
1071 pushEHDestructors();
1074 AggregatedInits.clear();
1077 void pushEHDestructors() {
1082 for (
unsigned i = 0; i < AggregatedInits.size(); ++i) {
1083 CXXCtorInitializer *MemberInit = AggregatedInits[i];
1088 LValue FieldLHS = LHS;
1090 CGF.
pushEHDestroy(dtorKind, FieldLHS.getAddress(), FieldType);
1094 void finish() { emitAggregatedInits(); }
1097 const CXXConstructorDecl *ConstructorDecl;
1098 bool MemcpyableCtor;
1099 FunctionArgList &Args;
1100 SmallVector<CXXCtorInitializer *, 16> AggregatedInits;
1103class AssignmentMemcpyizer :
public FieldMemcpyizer {
1107 FieldDecl *getMemcpyableField(Stmt *S) {
1108 if (!AssignmentsMemcpyable)
1110 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
1112 if (BO->getOpcode() != BO_Assign)
1114 MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS());
1118 if (!Field || !isMemcpyableField(Field))
1120 Stmt *RHS = BO->getRHS();
1121 if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS))
1122 RHS = EC->getSubExpr();
1125 if (MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
1126 if (ME2->getMemberDecl() == Field)
1130 }
else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) {
1131 CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
1134 MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument());
1138 if (!Field || !isMemcpyableField(Field))
1140 MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0));
1141 if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->
getMemberDecl()))
1144 }
else if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
1145 FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1146 if (!FD || FD->
getBuiltinID() != Builtin::BI__builtin_memcpy)
1148 Expr *DstPtr = CE->
getArg(0);
1149 if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr))
1150 DstPtr = DC->getSubExpr();
1151 UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr);
1152 if (!DUO || DUO->
getOpcode() != UO_AddrOf)
1154 MemberExpr *ME = dyn_cast<MemberExpr>(DUO->
getSubExpr());
1158 if (!Field || !isMemcpyableField(Field))
1160 Expr *SrcPtr = CE->
getArg(1);
1161 if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr))
1162 SrcPtr = SC->getSubExpr();
1163 UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr);
1164 if (!SUO || SUO->
getOpcode() != UO_AddrOf)
1166 MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->
getSubExpr());
1167 if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->
getMemberDecl()))
1175 bool AssignmentsMemcpyable;
1176 SmallVector<Stmt *, 16> AggregatedStmts;
1179 AssignmentMemcpyizer(CodeGenFunction &CGF,
const CXXMethodDecl *AD,
1180 FunctionArgList &Args)
1181 : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]),
1182 AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) {
1183 assert(Args.size() == 2);
1186 void emitAssignment(Stmt *S) {
1187 FieldDecl *F = getMemcpyableField(S);
1189 addMemcpyableField(F);
1190 AggregatedStmts.push_back(S);
1192 emitAggregatedStmts();
1197 void emitAggregatedStmts() {
1198 if (AggregatedStmts.size() <= 1) {
1199 if (!AggregatedStmts.empty()) {
1200 CopyingValueRepresentation CVR(CGF);
1208 AggregatedStmts.clear();
1211 void finish() { emitAggregatedStmts(); }
1233 bool ConstructVBases = CtorType !=
Ctor_Base &&
1240 llvm::BasicBlock *BaseCtorContinueBB =
nullptr;
1241 if (ConstructVBases &&
1242 !
CGM.getTarget().getCXXABI().hasConstructorVariants()) {
1243 BaseCtorContinueBB =
1244 CGM.getCXXABI().EmitCtorCompleteObjectHandler(*
this, ClassDecl);
1245 assert(BaseCtorContinueBB);
1249 auto AllInits = CD->
inits();
1252 auto VirtualBaseEnd = std::find_if(
1254 return !(Init->isBaseInitializer() && Init->isBaseVirtual());
1257 auto NonVirtualBaseEnd = std::find_if(VirtualBaseEnd, AllInits.end(),
1259 return !Init->isBaseInitializer();
1263 auto VirtualBaseInits = llvm::make_range(AllInits.begin(), VirtualBaseEnd);
1264 auto NonVirtualBaseInits =
1265 llvm::make_range(VirtualBaseEnd, NonVirtualBaseEnd);
1266 auto MemberInits = llvm::make_range(NonVirtualBaseEnd, AllInits.end());
1269 if (ConstructVBases) {
1272 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1273 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1280 if (BaseCtorContinueBB) {
1282 Builder.CreateBr(BaseCtorContinueBB);
1290 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1291 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1301 ConstructorMemcpyizer CM(*
this, CD, Args);
1303 assert(!
Member->isBaseInitializer());
1304 assert(
Member->isAnyMemberInitializer() &&
1305 "Delegating initializer on non-delegating constructor");
1306 CM.addMemberInitializer(
Member);
1314 llvm::Value *ShouldDeleteCondition) {
1317 llvm::BasicBlock *callDeleteBB =
1321 llvm::Value *CheckTheBitForArrayDestroy = CGF.
Builder.CreateAnd(
1322 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 2));
1323 llvm::Value *ShouldDestroyArray =
1325 CGF.
Builder.CreateCondBr(ShouldDestroyArray, ScalarBB, VectorBB);
1329 llvm::Value *numElements =
nullptr;
1330 llvm::Value *allocatedPtr =
nullptr;
1334 allocatedPtr, cookieSize);
1340 assert(numElements &&
"no element count for a type with a destructor!");
1348 ThisPtr.
getElementType(), arrayBegin, numElements,
"delete.end");
1359 llvm::Value *CheckTheBitForDeleteCall = CGF.
Builder.CreateAnd(
1360 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
1362 llvm::Value *ShouldCallDelete =
1369 if (Dtor->getArrayOperatorDelete()) {
1370 if (!Dtor->getGlobalArrayOperatorDelete()) {
1373 numElements, cookieSize);
1378 llvm::Value *CheckTheBitForGlobDeleteCall = CGF.
Builder.CreateAnd(
1379 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
1381 llvm::Value *ShouldCallGlobDelete =
1383 llvm::BasicBlock *GlobDelete =
1385 llvm::BasicBlock *ClassDelete =
1387 CGF.
Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
1391 numElements, cookieSize);
1398 llvm::Constant *GlobalDeleteWrapper =
1400 Dtor->getGlobalArrayOperatorDelete());
1403 if (Dtor->hasAttr<DLLExportAttr>())
1405 CGF.
EmitDeleteCall(Dtor->getGlobalArrayOperatorDelete(), allocatedPtr,
1407 numElements, cookieSize, GlobalDeleteWrapper);
1428 if (DtorType !=
Dtor_Base && Dtor->getParent()->isAbstract()) {
1433 Stmt *Body = Dtor->getBody();
1449 QualType ThisTy = Dtor->getFunctionObjectParameterType();
1458 bool isTryBody = isa_and_nonnull<CXXTryStmt>(Body);
1473 llvm_unreachable(
"not expecting a unified dtor");
1475 llvm_unreachable(
"not expecting a COMDAT");
1477 llvm_unreachable(
"already handled deleting case");
1479 llvm_unreachable(
"already handled vector deleting case");
1482 assert((Body ||
getTarget().getCXXABI().isMicrosoft()) &&
1483 "can't emit a dtor without a body for non-Microsoft ABIs");
1489 QualType ThisTy = Dtor->getFunctionObjectParameterType();
1508 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1509 CGM.getCodeGenOpts().OptimizationLevel > 0)
1519 assert(Dtor->isImplicit() &&
"bodyless dtor not implicit");
1525 CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
1543 "Body of an implicit assignment operator should be compound stmt.");
1550 AssignmentMemcpyizer AM(*
this, AssignOp, Args);
1551 for (
auto *I : RootCS->
body())
1552 AM.emitAssignment(I);
1566struct CallDtorDelete final : EHScopeStack::Cleanup {
1573 LoadThisForDtorDelete(CGF, Dtor),
1584 llvm::Value *ShouldDeleteCondition,
1585 bool ReturnAfterDelete) {
1587 const CXXRecordDecl *ClassDecl =
Dtor->getParent();
1588 const FunctionDecl *OD =
Dtor->getOperatorDelete();
1590 "unexpected value for ReturnAfterDelete");
1605 llvm::Value *Check3rdBit = CGF.
Builder.CreateAnd(
1606 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
1608 CGF.
Builder.CreateCondBr(ShouldCallDtor, DontCallDtor, CallDtor);
1610 QualType ThisTy =
Dtor->getFunctionObjectParameterType();
1614 CGF.
Builder.CreateBr(DontCallDtor);
1620 llvm::Value *Check1stBit = CGF.
Builder.CreateAnd(
1621 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
1623 CGF.
Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
1626 auto EmitDeleteAndGoToEnd = [&](
const FunctionDecl *DeleteOp,
1627 llvm::Constant *CalleeOverride =
nullptr) {
1630 nullptr, CharUnits(),
1632 if (ReturnAfterDelete)
1635 CGF.
Builder.CreateBr(continueBB);
1640 if (
const FunctionDecl *GlobOD =
Dtor->getOperatorGlobalDelete();
1644 llvm::Value *CheckTheBitForGlobDeleteCall = CGF.
Builder.CreateAnd(
1645 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
1646 llvm::Value *ShouldCallGlobDelete =
1648 llvm::BasicBlock *GlobDelete =
1650 llvm::BasicBlock *ClassDelete =
1652 CGF.
Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
1658 llvm::Constant *GlobalDeleteWrapper =
1662 if (
Dtor->hasAttr<DLLExportAttr>())
1664 EmitDeleteAndGoToEnd(GlobOD, GlobalDeleteWrapper);
1667 EmitDeleteAndGoToEnd(OD);
1671struct CallDtorDeleteConditional final : EHScopeStack::Cleanup {
1672 llvm::Value *ShouldDeleteCondition;
1675 CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition)
1676 : ShouldDeleteCondition(ShouldDeleteCondition) {
1677 assert(ShouldDeleteCondition !=
nullptr);
1680 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1681 EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition,
1686class DestroyField final :
public EHScopeStack::Cleanup {
1687 const FieldDecl *field;
1689 bool useEHCleanupForArray;
1693 bool useEHCleanupForArray)
1694 : field(field), destroyer(destroyer),
1695 useEHCleanupForArray(useEHCleanupForArray) {}
1697 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1704 assert(LV.isSimple());
1706 CGF.
emitDestroy(LV.getAddress(), field->getType(), destroyer,
1707 flags.isForNormalCleanup() && useEHCleanupForArray);
1711class DeclAsInlineDebugLocation {
1713 llvm::DILocation *InlinedAt;
1714 std::optional<ApplyDebugLocation> Location;
1717 DeclAsInlineDebugLocation(CodeGenFunction &CGF,
const NamedDecl &
Decl)
1718 : DI(CGF.getDebugInfo()) {
1723 Location.emplace(CGF,
Decl.getLocation());
1726 ~DeclAsInlineDebugLocation() {
1734static void EmitSanitizerDtorCallback(
1736 std::optional<CharUnits::QuantityType> PoisonSize = {}) {
1740 SmallVector<llvm::Value *, 2> Args = {
Ptr};
1741 SmallVector<llvm::Type *, 2> ArgTypes = {CGF.
VoidPtrTy};
1743 if (PoisonSize.has_value()) {
1744 Args.emplace_back(llvm::ConstantInt::get(CGF.
SizeTy, *PoisonSize));
1745 ArgTypes.emplace_back(CGF.
SizeTy);
1748 llvm::FunctionType *FnType =
1749 llvm::FunctionType::get(CGF.
VoidTy, ArgTypes,
false);
1756EmitSanitizerDtorFieldsCallback(
CodeGenFunction &CGF, llvm::Value *Ptr,
1758 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_fields", Ptr,
1763struct SanitizeDtorTrivialBase final : EHScopeStack::Cleanup {
1764 const CXXRecordDecl *BaseClass;
1766 SanitizeDtorTrivialBase(
const CXXRecordDecl *Base,
bool BaseIsVirtual)
1767 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
1769 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1770 const CXXRecordDecl *DerivedClass =
1776 const ASTRecordLayout &BaseLayout =
1778 CharUnits BaseSize = BaseLayout.
getSize();
1785 DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass);
1786 EmitSanitizerDtorFieldsCallback(CGF,
Addr.emitRawPointer(CGF),
1790 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1794class SanitizeDtorFieldRange final :
public EHScopeStack::Cleanup {
1795 const CXXDestructorDecl *
Dtor;
1796 unsigned StartIndex;
1800 SanitizeDtorFieldRange(
const CXXDestructorDecl *Dtor,
unsigned StartIndex,
1802 :
Dtor(
Dtor), StartIndex(StartIndex), EndIndex(EndIndex) {}
1807 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1808 const ASTContext &Context = CGF.
getContext();
1809 const ASTRecordLayout &Layout =
1816 llvm::ConstantInt *OffsetSizePtr =
1819 llvm::Value *OffsetPtr =
1822 CharUnits PoisonEnd;
1828 CharUnits PoisonSize = PoisonEnd - PoisonStart;
1833 DeclAsInlineDebugLocation InlineHere(
1834 CGF, **std::next(
Dtor->getParent()->field_begin(), StartIndex));
1835 EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.
getQuantity());
1838 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1842class SanitizeDtorVTable final :
public EHScopeStack::Cleanup {
1843 const CXXDestructorDecl *
Dtor;
1846 SanitizeDtorVTable(
const CXXDestructorDecl *Dtor) :
Dtor(
Dtor) {}
1849 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1850 assert(
Dtor->getParent()->isDynamicClass());
1857 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_vptr", VTablePtr);
1861class SanitizeDtorCleanupBuilder {
1862 ASTContext &Context;
1863 EHScopeStack &EHStack;
1864 const CXXDestructorDecl *DD;
1865 std::optional<unsigned> StartIndex;
1868 SanitizeDtorCleanupBuilder(ASTContext &Context, EHScopeStack &EHStack,
1869 const CXXDestructorDecl *DD)
1870 : Context(Context), EHStack(EHStack), DD(DD), StartIndex(std::nullopt) {}
1871 void PushCleanupForField(
const FieldDecl *Field) {
1874 unsigned FieldIndex =
Field->getFieldIndex();
1877 StartIndex = FieldIndex;
1878 }
else if (StartIndex) {
1880 *StartIndex, FieldIndex);
1881 StartIndex = std::nullopt;
1901 "Should not emit dtor epilogue for non-exported trivial dtor!");
1907 "operator delete missing - EnterDtorCleanups");
1908 if (CXXStructorImplicitParamValue) {
1912 EmitConditionalDtorDeleteCall(*
this, CXXStructorImplicitParamValue,
1915 EHStack.pushCleanup<CallDtorDeleteConditional>(
1921 LoadThisForDtorDelete(*
this, DD),
1922 getContext().getCanonicalTagType(ClassDecl));
1941 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1948 for (
const auto &
Base : ClassDecl->
vbases()) {
1949 auto *BaseClassDecl =
Base.getType()->castAsCXXRecordDecl();
1950 if (BaseClassDecl->hasTrivialDestructor()) {
1954 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1955 SanOpts.has(SanitizerKind::Memory) && !BaseClassDecl->isEmpty())
1971 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1977 for (
const auto &
Base : ClassDecl->
bases()) {
1979 if (
Base.isVirtual())
1985 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1998 bool SanitizeFields =
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1999 SanOpts.has(SanitizerKind::Memory);
2003 for (
const auto *Field : ClassDecl->
fields()) {
2005 SanitizeBuilder.PushCleanupForField(Field);
2013 const RecordType *RT =
type->getAsUnionType();
2014 if (RT && RT->getDecl()->isAnonymousStructOrUnion())
2018 EHStack.pushCleanup<DestroyField>(
2023 SanitizeBuilder.End();
2038 bool NewPointerIsChecked,
2039 bool zeroInitialize) {
2041 llvm::Value *numElements =
2045 NewPointerIsChecked, zeroInitialize);
2059 const CXXConstructExpr *E,
bool NewPointerIsChecked,
bool zeroInitialize) {
2065 llvm::CondBrInst *zeroCheckBranch =
nullptr;
2068 llvm::ConstantInt *constantCount = dyn_cast<llvm::ConstantInt>(numElements);
2069 if (constantCount) {
2071 if (constantCount->isZero())
2077 llvm::Value *iszero =
Builder.CreateIsNull(numElements,
"isempty");
2078 zeroCheckBranch =
Builder.CreateCondBr(iszero, loopBB, loopBB);
2085 llvm::Value *arrayEnd =
Builder.CreateInBoundsGEP(
2086 elementType, arrayBegin, numElements,
"arrayctor.end");
2089 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
2092 llvm::PHINode *cur =
2093 Builder.CreatePHI(arrayBegin->getType(), 2,
"arrayctor.cur");
2094 cur->addIncoming(arrayBegin, entryBB);
2097 if (
CGM.shouldEmitConvergenceTokens())
2145 llvm::Value *next =
Builder.CreateInBoundsGEP(
2146 elementType, cur, llvm::ConstantInt::get(
SizeTy, 1),
"arrayctor.next");
2147 cur->addIncoming(next,
Builder.GetInsertBlock());
2150 llvm::Value *done =
Builder.CreateICmpEQ(next, arrayEnd,
"arrayctor.done");
2152 Builder.CreateCondBr(done, contBB, loopBB);
2155 if (zeroCheckBranch)
2156 zeroCheckBranch->setSuccessor(0, contBB);
2158 if (
CGM.shouldEmitConvergenceTokens())
2179 llvm::Value *ThisPtr =
2182 if (SlotAS != ThisAS) {
2184 llvm::Type *NewType =
2196 assert(E->
getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
2209 ? EvaluationOrder::ForceLeftToRight
2210 : EvaluationOrder::Default;
2247 bool NewPointerIsChecked, llvm::CallBase **CallOrInvoke) {
2250 if (!NewPointerIsChecked)
2256 assert(Args.size() == 1 &&
"trivial default ctor with args");
2264 assert(Args.size() == 2 &&
"unexpected argcount for trivial ctor");
2267 Args[1].getRValue(*this).getScalarVal(), SrcTy);
2275 bool PassPrototypeArgs =
true;
2288 CGM.getCXXABI().addImplicitConstructorArgs(*
this, D,
Type, ForVirtualBase,
2311 if (
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2313 CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) &&
2314 CGM.getCodeGenOpts().StrictVTablePointers)
2327 if (InheritedFromVBase &&
2328 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
2333 Args.push_back(ThisArg);
2334 }
else if (!CXXInheritedCtorInitExprArgs.empty()) {
2336 assert(CXXInheritedCtorInitExprArgs.size() >= D->
getNumParams() &&
2337 "wrong number of parameters for inherited constructor call");
2338 Args = CXXInheritedCtorInitExprArgs;
2342 Args.push_back(ThisArg);
2344 assert(OuterCtor->getNumParams() == D->
getNumParams());
2345 assert(!OuterCtor->isVariadic() &&
"should have been inlined");
2347 for (
const auto *Param : OuterCtor->parameters()) {
2349 OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
2354 if (Param->hasAttr<PassObjectSizeAttr>()) {
2355 auto *POSParam = SizeArguments[Param];
2356 assert(POSParam &&
"missing pass_object_size value for forwarding");
2376 CXXInheritedCtorInitExprArgs = Args;
2383 CGM.getCXXABI().addImplicitConstructorArgs(*
this, Ctor, CtorType,
2387 assert(Args.size() >= Params.size() &&
"too few arguments for call");
2388 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
2390 const RValue &RV = Args[I].getRValue(*
this);
2391 assert(!RV.
isComplex() &&
"complex indirect params not supported");
2405 CGM.getCXXABI().EmitInstanceFunctionProlog(*
this);
2406 CXXThisValue = CXXABIThisValue;
2413 llvm::Value *VTableGlobal =
2421 if (!NonVirtualOffset.
isZero())
2426 llvm::Value *VPtrValue =
2429 Builder.CreateICmpEQ(VPtrValue, VTableGlobal,
"cmp.vtables");
2435 if (
CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))
2453 llvm::Type *t =
CGM.getTypes().ConvertType(QT);
2455 llvm::Value *SrcVal =
Builder.CreateBitCast(Val, t);
2473 FunctionArgList::const_iterator I = Args.begin(), E = Args.end();
2474 assert(I != E &&
"no parameters to constructor");
2479 This, (*I)->getType()->getPointeeType())),
2485 if (
CGM.getCXXABI().NeedsVTTParameter(
CurGD)) {
2486 assert(I != E &&
"cannot skip vtt parameter, already done with args");
2487 assert((*I)->getType()->isPointerType() &&
2488 "skipping parameter not of vtt type");
2493 for (; I != E; ++I) {
2500 true,
This, DelegateArgs,
2506struct CallDelegatingCtorDtor final : EHScopeStack::Cleanup {
2518 QualType ThisTy = Dtor->getFunctionObjectParameterType();
2520 true,
Addr, ThisTy);
2545 EHStack.pushCleanup<CallDelegatingCtorDtor>(
2552 bool ForVirtualBase,
2555 CGM.getCXXABI().EmitDestructorCall(*
this, DD,
Type, ForVirtualBase,
2560struct CallLocalDtor final : EHScopeStack::Cleanup {
2589 assert(D && D->
isUsed() &&
"destructor not marked as used!");
2595 llvm::Value *VTableAddressPoint =
2596 CGM.getCXXABI().getVTableAddressPointInStructor(
2599 if (!VTableAddressPoint)
2603 llvm::Value *VirtualOffset =
nullptr;
2606 if (
CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*
this, Vptr)) {
2610 VirtualOffset =
CGM.getCXXABI().GetVirtualBaseClassOffset(
2620 if (!NonVirtualOffset.
isZero() || VirtualOffset)
2622 *
this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.
VTableClass,
2627 unsigned GlobalsAS =
CGM.getDataLayout().getDefaultGlobalsAddressSpace();
2628 llvm::Type *PtrTy = llvm::PointerType::get(
CGM.getLLVMContext(), GlobalsAS);
2633 if (
auto AuthenticationInfo =
CGM.getVTablePointerAuthInfo(
2635 VTableAddressPoint =
2638 llvm::StoreInst *Store =
Builder.CreateStore(VTableAddressPoint, VTableField);
2640 CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
2641 if (
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2642 CGM.getCodeGenOpts().StrictVTablePointers)
2643 CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.
VTableClass);
2653 false, VTableClass, VBases,
2661 bool BaseIsNonVirtualPrimaryBase,
2667 if (!BaseIsNonVirtualPrimaryBase) {
2669 VPtr Vptr = {
Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
2670 Vptrs.push_back(Vptr);
2676 for (
const auto &I : RD->
bases()) {
2677 auto *BaseDecl = I.getType()->castAsCXXRecordDecl();
2679 if (!BaseDecl->isDynamicClass())
2684 bool BaseDeclIsNonVirtualPrimaryBase;
2686 if (I.isVirtual()) {
2688 if (!VBases.insert(BaseDecl).second)
2696 BaseDeclIsNonVirtualPrimaryBase =
false;
2701 BaseOffsetFromNearestVBase =
2703 BaseDeclIsNonVirtualPrimaryBase = Layout.
getPrimaryBase() == BaseDecl;
2708 I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
2709 BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
2719 if (
CGM.getCXXABI().doStructorsInitializeVPtrs(RD))
2724 CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*
this, RD);
2730 Address VTablePtrSrc =
This.withElementType(VTableTy);
2731 llvm::Instruction *VTable =
Builder.CreateLoad(VTablePtrSrc,
"vtable");
2733 CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo);
2735 if (
auto AuthenticationInfo =
2736 CGM.getVTablePointerAuthInfo(
this, RD,
This.emitRawPointer(*
this))) {
2757 if (
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2758 CGM.getCodeGenOpts().StrictVTablePointers)
2759 CGM.DecorateInstructionWithInvariantGroup(VTable, RD);
2800 llvm::Value *VTable,
2802 if (
SanOpts.has(SanitizerKind::CFIVCall))
2810 else if ((
CGM.getCodeGenOpts().WholeProgramVTables &&
2811 !
CGM.AlwaysHasLTOVisibilityPublic(RD)) ||
2812 CGM.getCodeGenOpts().DevirtualizeSpeculatively) {
2814 llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(Ty);
2815 llvm::Value *TypeId = llvm::MetadataAsValue::get(
CGM.getLLVMContext(), MD);
2821 llvm::Intrinsic::ID IID =
CGM.HasHiddenLTOVisibility(RD)
2822 ? llvm::Intrinsic::type_test
2823 : llvm::Intrinsic::public_type_test;
2824 llvm::Value *TypeTest =
2825 Builder.CreateCall(
CGM.getIntrinsic(IID), {VTable, TypeId});
2826 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
2832static std::pair<SanitizerKind::SanitizerOrdinal, llvm::SanitizerStatKind>
2836 return std::make_pair(SanitizerKind::SO_CFIVCall, llvm::SanStat_CFI_VCall);
2838 return std::make_pair(SanitizerKind::SO_CFINVCall,
2839 llvm::SanStat_CFI_NVCall);
2841 return std::make_pair(SanitizerKind::SO_CFIDerivedCast,
2842 llvm::SanStat_CFI_DerivedCast);
2844 return std::make_pair(SanitizerKind::SO_CFIUnrelatedCast,
2845 llvm::SanStat_CFI_UnrelatedCast);
2849 llvm_unreachable(
"unexpected sanitizer kind");
2851 llvm_unreachable(
"Unknown CFITypeCheckKind enum");
2855 llvm::Value *VTable,
2858 if (!
SanOpts.has(SanitizerKind::CFICastStrict))
2863 SanitizerHandler::CFICheckFail);
2875 const auto *ClassDecl =
T->getAsCXXRecordDecl();
2882 if (!
SanOpts.has(SanitizerKind::CFICastStrict))
2887 SanitizerHandler::CFICheckFail);
2889 llvm::BasicBlock *ContBlock =
nullptr;
2892 llvm::Value *DerivedNotNull =
2898 Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
2903 llvm::Value *VTable;
2904 std::tie(VTable, ClassDecl) =
2905 CGM.getCXXABI().LoadVTablePtr(*
this, Derived, ClassDecl);
2916 llvm::Value *VTable,
2921 if (!
CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
2922 !
CGM.HasHiddenLTOVisibility(RD))
2926 if (
getContext().getNoSanitizeList().containsType(
2931 llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(
T);
2932 llvm::Value *TypeId = llvm::MetadataAsValue::get(
getLLVMContext(), MD);
2933 llvm::Value *TypeTest =
Builder.CreateCall(
2934 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, TypeId});
2937 CGM.getCodeGenOpts().SanitizeCfiCrossDso);
2941 llvm::Metadata *MD, llvm::Value *VTable,
2943 bool UseCrossDsoSlowPath) {
2948 llvm::ConstantInt *CrossDsoTypeId =
2949 UseCrossDsoSlowPath ?
CGM.CreateCrossDsoCfiTypeId(MD) :
nullptr;
2950 if (!CrossDsoTypeId && (
CGM.getCodeGenOpts().SanitizeTrap.has(M) ||
2951 CGM.getCodeGenOpts().SanitizeMinimalRuntime)) {
2952 EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail, {},
2957 if (
CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
2962 llvm::Constant *StaticData[] = {
2963 llvm::ConstantInt::get(
Int8Ty, TCK),
2968 if (CrossDsoTypeId) {
2973 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
2974 CGM.getLLVMContext(),
2975 llvm::MDString::get(
CGM.getLLVMContext(),
"all-vtables"));
2976 llvm::Value *ValidVtable =
Builder.CreateCall(
2977 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
2978 EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
2979 StaticData, {VTable, ValidVtable});
2983 if (!
CGM.getCodeGenOpts().WholeProgramVTables ||
2984 !
CGM.HasHiddenLTOVisibility(RD))
2987 if (
CGM.getCodeGenOpts().VirtualFunctionElimination)
2990 if (!
SanOpts.has(SanitizerKind::CFIVCall) ||
2991 !
CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall))
3000 const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy,
3002 auto CheckOrdinal = SanitizerKind::SO_CFIVCall;
3003 auto CheckHandler = SanitizerHandler::CFICheckFail;
3007 llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(
T);
3008 llvm::Value *TypeId = llvm::MetadataAsValue::get(
CGM.getLLVMContext(), MD);
3010 auto CheckedLoadIntrinsic =
CGM.getLangOpts().RelativeCXXABIVTables
3011 ? llvm::Intrinsic::type_checked_load_relative
3012 : llvm::Intrinsic::type_checked_load;
3013 llvm::Value *CheckedLoad =
Builder.CreateCall(
3014 CGM.getIntrinsic(CheckedLoadIntrinsic),
3015 {VTable, llvm::ConstantInt::get(Int32Ty, VTableByteOffset), TypeId});
3017 llvm::Value *CheckResult =
Builder.CreateExtractValue(CheckedLoad, 1);
3020 if (
SanOpts.has(SanitizerKind::CFIVCall) &&
3021 !
getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
3024 EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler, {}, {});
3027 return Builder.CreateBitCast(
Builder.CreateExtractValue(CheckedLoad, 0),
3036 calleeFnInfo = &
CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
3041 CGM.getTypes().GetFunctionType(*calleeFnInfo));
3048 if (!resultType->isVoidType() &&
3061 RValue RV =
EmitCall(*calleeFnInfo, callee, returnSlot, callArgs);
3064 if (!resultType->isVoidType() && returnSlot.
isNull()) {
3065 if (
getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
3068 EmitReturnOfRValue(RV, resultType);
3083 CGM.ErrorUnsupported(
CurCodeDecl,
"lambda conversion to variadic function");
3100 "generic lambda interconversion to block not implemented");
3109 CGM.ErrorUnsupported(MD,
"lambda conversion to variadic function");
3141 llvm::FoldingSetInsertToken InsertToken;
3144 assert(CorrespondingCallOpSpecialization);
3149 if (hasInAllocaArg(MD)) {
3151 llvm::Function *ImplFn =
nullptr;
3166 CGM.ErrorUnsupported(MD,
"lambda conversion to variadic function");
3174 llvm::Value *ThisArg =
CurFn->getArg(0);
3182 llvm::Function **ImplFn) {
3184 CGM.getTypes().arrangeCXXMethodDeclaration(CallOp);
3185 llvm::Function *CallOpFn =
3192 ArgTypes.push_back(I->type);
3193 *ImplFnInfo = &
CGM.getTypes().arrangeLLVMFunctionInfo(
3202 StringRef CallOpName = CallOpFn->getName();
3203 std::string ImplName;
3204 if (
size_t Pos = CallOpName.find_first_of(
"<lambda"))
3205 ImplName = (
"?__impl@" + CallOpName.drop_front(Pos)).str();
3207 ImplName = (
"__impl" + CallOpName).str();
3209 llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName);
3211 Fn = llvm::Function::Create(
CGM.getTypes().GetFunctionType(**ImplFnInfo),
3212 llvm::GlobalValue::InternalLinkage, ImplName,
3214 CGM.SetInternalFunctionAttributes(CallOp, Fn, **ImplFnInfo);
3218 CodeGenFunction(
CGM).GenerateCode(GD, Fn, **ImplFnInfo);
3219 CGM.SetLLVMFunctionAttributesForDefinition(D, Fn);
static Address ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, CharUnits nonVirtualOffset, llvm::Value *virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase)
static const CXXRecordDecl * LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD)
static void EmitBaseInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *BaseInit)
static std::pair< SanitizerKind::SanitizerOrdinal, llvm::SanitizerStatKind > SanitizerInfoFromCFICheckKind(CodeGenFunction::CFITypeCheckKind TCK)
Converts the CFITypeCheckKind into SanitizerKind::SanitizerOrdinal and llvm::SanitizerStatKind.
static void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD, CodeGenFunction &CGF, llvm::Value *ShouldDeleteCondition)
static void EmitMemberInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *MemberInit, const CXXConstructorDecl *Constructor, FunctionArgList &Args)
static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF, CXXCtorInitializer *MemberInit, LValue &LHS)
static bool canEmitDelegateCallArgs(CIRGenModule &cgm, ASTContext &ctx, const CXXConstructorDecl *d, CXXCtorType type)
Defines the C++ template declaration subclasses.
a trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const NoSanitizeList & getNoSanitizeList() const
bool arePFPFieldsTriviallyCopyable(const RecordDecl *RD) const
Returns whether this record's PFP fields (if any) are trivially copyable (i.e.
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static bool isPFPField(const FieldDecl *Field)
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
unsigned getTargetAddressSpace(LangAS AS) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
CharUnits getSize() const
getSize - Get the record size in characters.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
Represents a block literal declaration, which is like an unnamed FunctionDecl.
capture_const_iterator capture_begin() const
ArrayRef< ParmVarDecl * > parameters() const
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
Represents a call to a C++ constructor.
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Represents a C++ constructor within a class.
init_iterator init_begin()
Retrieve an iterator to the first initializer.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Represents a C++ base or member initializer.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
Expr * getInit() const
Get the initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a C++ destructor within a class.
const FunctionDecl * getOperatorDelete() const
Expr * getOperatorDeleteThisArg() const
Represents a call to an inherited base class constructor from an inheriting constructor.
SourceLocation getLocation() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
QualType getFunctionObjectParameterType() const
bool isMemcpyEquivalentSpecialMember(const ASTContext &Ctx) const
Returns whether this is a copy/move constructor or assignment operator that can be implemented as a m...
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
method_range methods() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
const CXXBaseSpecifier *const * path_const_iterator
This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isPositive() const
Test whether the quantity is greater than zero.
bool isZero() const
Test whether the quantity equals zero.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits Zero()
Construct a CharUnits quantity of zero.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
bool isSanitizerChecked() const
Address getAddress() const
Qualifiers getQualifiers() const
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
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.
Overlap_t mayOverlap() const
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
A scoped helper to set the current debug location to the specified location or preferred location of ...
A scoped helper to set the current debug location to an inlined location.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
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.
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
void setInlinedAt(llvm::DILocation *InlinedAt)
Update the current inline scope.
llvm::DILocation * getInlinedAt() const
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
FunctionType::ExtInfo getExtInfo() const
ABIArgInfo & getReturnInfo()
const_arg_iterator arg_begin() const
CanQualType getReturnType() const
const_arg_iterator arg_end() const
RequiredArgs getRequiredArgs() const
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
static ParamValue forIndirect(Address addr)
static ParamValue forDirect(llvm::Value *value)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void emitArrayDestroy(llvm::Value *begin, llvm::Value *end, QualType elementType, CharUnits elementAlign, Destroyer *destroyer, bool checkZeroLength, bool useEHCleanup)
emitArrayDestroy - Destroys all the elements of the given array, beginning from last to first.
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass, VTableAuthMode AuthMode=VTableAuthMode::Authenticate)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, const FunctionArgList &Args)
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)
Determine whether a field initialization may overlap some other object.
void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, const FunctionArgList &Args, SourceLocation Loc)
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
SanitizerSet SanOpts
Sanitizers enabled for this function.
CodeGenUtils::EvaluationOrder EvaluationOrder
void EmitAsanPrologueOrEpilogue(bool Prologue)
void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase, bool Delegating, CallArgList &Args)
Emit a call to an inheriting constructor (that is, one that invokes a constructor inherited from a ba...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
Address LoadCXXThisAddress()
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)
void pushEHDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushEHDestroy - Push the standard destructor for the given type as an EH-only cleanup.
void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)
void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD, CallArgList &CallArgs)
Address GetAddressOfBaseClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue, SourceLocation Loc)
GetAddressOfBaseClass - This function will add the necessary delta to the load of 'this' and returns ...
LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T)
Given a value of type T* that may not be to a complete object, construct an l-value with the natural ...
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
pushRegularPartialArrayCleanup - Push an EH cleanup to destroy already-constructed elements of the gi...
SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack
Stack to track the controlled convergence tokens.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, CallArgList &CallArgs, const CGFunctionInfo *CallOpFnInfo=nullptr, llvm::Constant *CallOpFn=nullptr)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD, const CXXRecordDecl *BaseRD, bool IsVirtual)
Determine whether a base class initialization may overlap some other object.
const LangOptions & getLangOpts() const
llvm::Value * EmitARCRetainAutoreleasedReturnValue(llvm::Value *value)
Retain the given object which is the result of a function call.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for RD using llvm....
void EmitConstructorBody(FunctionArgList &Args)
EmitConstructorBody - Emits the body of the current constructor.
const CodeGen::CGBlockInfo * BlockInfo
void EmitAggregateCopyCtor(LValue Dest, LValue Src, AggValueSlot::Overlap_t MayOverlap)
Address makeNaturalAddressForPointer(llvm::Value *Ptr, QualType T, CharUnits Alignment=CharUnits::Zero(), bool ForPointeeType=false, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
Construct an address with the natural alignment of T.
static Destroyer destroyCXXObject
void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp, const CGFunctionInfo **ImplFnInfo, llvm::Function **ImplFn)
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, bool NewPointerIsChecked, bool ZeroInitialization=false)
EmitCXXAggrConstructorCall - Emit a loop to call a particular constructor for each of several members...
VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass)
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
@ TCK_ConstructorCall
Checking the 'this' pointer for a constructor call.
@ TCK_UpcastToVirtualBase
Checking the operand of a cast to a virtual base object.
@ TCK_Load
Checking the operand of a load. Must be suitably sized and aligned.
@ TCK_Upcast
Checking the operand of a cast to a base object.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void PushDestructorCleanup(QualType T, Address Addr)
PushDestructorCleanup - Push a cleanup to call the complete-object destructor of an object of the giv...
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
llvm::ConvergenceControlInst * emitConvergenceLoopToken(llvm::BasicBlock *BB)
llvm::SmallPtrSet< const CXXRecordDecl *, 4 > VisitedVirtualBasesSetTy
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field, bool IsInBounds=true)
const TargetInfo & getTarget() const
Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, bool IsInBounds, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Emit the address of a field using a member data pointer.
void maybeCreateMCDCCondBitmap()
Allocate a temp value on the stack that MCDC can use to track condition results.
Address GetAddrOfBlockDecl(const VarDecl *var)
RawAddress CreateIRTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateIRTempWithoutCast - Create a temporary IR object of the given type, with appropriate alignment.
void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type)
EnterDtorCleanups - Enter the cleanups necessary to complete the given phase of destruction for a des...
llvm::Value * EmitPointerAuthSign(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, AggValueSlot ThisAVS, const CXXConstructExpr *E)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset, SourceLocation Loc)
Emit a type checked load from the given vtable.
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This)
Emit assumption load for all bases.
CGDebugInfo * getDebugInfo()
void EmitDestructorBody(FunctionArgList &Args)
EmitDestructorBody - Emits the body of the current destructor.
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...
Address GetAddressOfDirectBaseInCompleteClass(Address Value, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, bool BaseIsVirtual)
GetAddressOfBaseOfCompleteClass - Convert the given pointer to a complete class to the given direct b...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args)
EmitCtorPrologue - This routine generates necessary code to initialize base classes and non-static da...
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
void EmitVTableCheck(CFITypeCheckKind TCK, CanQualType T, llvm::Metadata *MD, llvm::Value *VTable, llvm::Value *TypeTest, SourceLocation Loc, bool UseCrossDsoSlowPath)
Emit a CFI check failure handler or trap for a vtable type test result.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init)
void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD)
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::Type * ConvertTypeForMem(QualType T)
void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, Address This, Address Src, const CXXConstructExpr *E)
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
void EmitLambdaBlockInvokeBody()
void EmitCfiSlowPathCheck(SanitizerKind::SanitizerOrdinal Ordinal, llvm::Value *Cond, llvm::ConstantInt *TypeId, llvm::Value *Ptr, ArrayRef< llvm::Constant * > StaticArgs)
Emit a slow path cross-DSO CFI check which calls __cfi_slowpath if Cond if false.
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D, bool ForVirtualBase, Address This, bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E)
Emit a call to a constructor inherited from a base class, passing the current constructor's arguments...
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
const FunctionDecl * getCurrentFunctionDecl() const
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits(), llvm::Constant *CalleeOverride=nullptr)
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCallAndMakeUnreachable()
Emit a call to '@llvm.trap()' and clear the current insert point.
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void InitializeVTablePointer(const VPtr &vptr)
Initialize the vtable pointer of the given subobject.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::LLVMContext & getLLVMContext()
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::SmallVector< VPtr, 4 > VPtrsVector
void InitializeVTablePointers(const CXXRecordDecl *ClassDecl)
void EmitVTableAssumptionLoad(const VPtr &vptr, Address This)
Emit assumption that vptr load == global vtable.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CharUnits getMinimumClassObjectSize(const CXXRecordDecl *CD)
Returns the minimum object size for an object of the given class type (or a class derived from it).
llvm::Constant * getOrCreateMSVCGlobalDeleteWrapper(const FunctionDecl *GlobOD)
Get or create the MSVC-compatible __global_delete wrapper for the given global operator delete,...
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Constant * GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd)
Returns the offset from a derived class to a class.
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
CGCXXABI & getCXXABI() const
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, const CXXRecordDecl *Class, CharUnits ExpectedTargetAlign)
Given a class pointer with an actual known alignment, and the expected alignment of an object at a dy...
void noteDirectGlobalDelete()
Note that global operator delete is directly used in this TU.
ASTContext & getContext() const
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, const FunctionDecl *ABIInfoFD, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
Address getAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
An abstract representation of an aligned address.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
CompoundStmt - This represents a group of statements like { stmt stmt }.
Represents the canonical version of C arrays with a specified constant size.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isDefaulted() const
Whether this function is defaulted.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Represents a prototype with parameter type info, e.g.
param_type_iterator param_type_begin() const
bool isVariadic() const
Whether this function prototype is variadic.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, llvm::FoldingSetInsertToken &InsertToken)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
const Decl * getDecl() const
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
std::string getQualifiedNameAsString() const
bool containsType(SanitizerMask Mask, StringRef MangledTypeName, StringRef Category=StringRef()) const
bool isAddressDiscriminated() const
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
The collection of all-type qualifiers we support.
bool hasObjCLifetime() const
LangAS getAddressSpace() const
field_range fields() const
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual bool callGlobalDeleteInDeletingDtor(const LangOptions &) const
Controls whether global operator delete is called by the deleting destructor or at the point where de...
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Expr * getSubExpr() const
Represents a variable declaration or definition.
bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit)
Return whether BaseInit initializes a base class that is dynamic, that is, one whose vtable pointer m...
bool canSkipVTablePointerInitialization(ASTContext &Ctx, const CXXDestructorDecl *Dtor)
Check whether we need to initialize any vtable pointers before calling this destructor.
bool fieldHasTrivialDestructorBody(ASTContext &Ctx, const FieldDecl *Field)
Check whether destructing Field has no observable behaviors, and thus can be skipped when creating a ...
bool isEmptyFieldForLayout(const ASTContext &Ctx, const FieldDecl *FD)
Return true iff the field is "empty", that is, either a zero-width bit-field or an isEmptyRecordForLa...
bool baseInitializerUsesThis(ASTContext &Ctx, const Expr *Init)
Check whether Init uses 'this' in a way which requires the vtable to be properly set.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
const FunctionProtoType * T
CXXDtorType
C++ destructor types.
@ Dtor_VectorDeleting
Vector deleting dtor.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Unified
GCC-style unified dtor.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
U cast(CodeGen::Address addr)
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
Similar to AddedStructorArgs, but only notes the number of additional arguments.
llvm::BasicBlock * getBlock() const
Struct with all information about dynamic [sub]class needed to set vptr.
const CXXRecordDecl * NearestVBase
const CXXRecordDecl * VTableClass
CharUnits OffsetFromNearestVBase
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
llvm::IntegerType * PtrDiffTy
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.