29#include "llvm/IR/Intrinsics.h"
30#include "llvm/IR/Metadata.h"
31#include "llvm/Support/SaveAndRestore.h"
32#include "llvm/Transforms/Utils/SanitizerStats.h"
52 return layout.getNonVirtualAlignment();
84 CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
97 return std::min(actualBaseAlign, expectedTargetAlign);
100 CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
120 if (actualBaseAlign >= expectedBaseAlign) {
121 return expectedTargetAlign;
127 return std::min(actualBaseAlign, expectedTargetAlign);
131 assert(
CurFuncDecl &&
"loading 'this' without a func declaration?");
135 if (CXXThisAlignment.isZero()) {
139 CXXThisAlignment =
CGM.getClassPointerAlignment(MD->getParent());
143 LoadCXXThis(), MD->getFunctionObjectParameterType(), CXXThisAlignment,
151 const Expr *E,
Address base, llvm::Value *memberPtr,
155 llvm::Value *ptr =
CGM.getCXXABI().EmitMemberDataPointerAddress(
156 *
this, E, base, memberPtr, memberPtrType, IsInBounds);
160 CGM.getNaturalTypeAlignment(memberType, BaseInfo, TBAAInfo);
161 memberAlign =
CGM.getDynamicOffsetAlignment(
178 assert(!
Base->isVirtual() &&
"Should not see virtual bases here!");
183 const auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
196 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
206 return llvm::ConstantInt::get(
PtrDiffTy, Offset.getQuantity());
216 bool BaseIsVirtual) {
231 if (!Offset.isZero()) {
233 V =
Builder.CreateConstInBoundsByteGEP(
V, Offset);
240 llvm::Value *virtualOffset,
const CXXRecordDecl *derivedClass,
243 assert(!nonVirtualOffset.
isZero() || virtualOffset !=
nullptr);
246 llvm::Value *baseOffset;
247 if (!nonVirtualOffset.
isZero()) {
248 llvm::Type *OffsetType =
254 llvm::ConstantInt::get(OffsetType, nonVirtualOffset.
getQuantity());
256 baseOffset = CGF.
Builder.CreateAdd(virtualOffset, baseOffset);
259 baseOffset = virtualOffset;
270 assert(nearestVBase &&
"virtual offset without vbase?");
286 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
295 if ((*Start)->isVirtual()) {
296 VBase = (*Start)->getType()->castAsCXXRecordDecl();
303 CharUnits NonVirtualOffset =
CGM.computeNonVirtualBaseClassOffset(
304 VBase ? VBase : Derived, Start, PathEnd);
309 if (VBase && Derived->
hasAttr<FinalAttr>()) {
312 NonVirtualOffset += vBaseOffset;
318 llvm::Type *PtrTy = llvm::PointerType::get(
322 CharUnits DerivedAlign =
CGM.getClassPointerAlignment(Derived);
326 if (NonVirtualOffset.
isZero() && !VBase) {
329 SkippedChecks.
set(SanitizerKind::Null, !NullCheckValue);
331 DerivedAlign, SkippedChecks);
333 return Value.withElementType(BaseValueTy);
336 llvm::BasicBlock *origBB =
nullptr;
337 llvm::BasicBlock *endBB =
nullptr;
341 if (NullCheckValue) {
342 origBB =
Builder.GetInsertBlock();
347 Builder.CreateCondBr(isNull, endBB, notNullBB);
353 SkippedChecks.
set(SanitizerKind::Null,
true);
355 Value.emitRawPointer(*
this), DerivedTy, DerivedAlign,
360 llvm::Value *VirtualOffset =
nullptr;
363 CGM.getCXXABI().GetVirtualBaseClassOffset(*
this,
Value, Derived, VBase);
368 VirtualOffset, Derived, VBase);
374 if (NullCheckValue) {
375 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
379 llvm::PHINode *PHI =
Builder.CreatePHI(PtrTy, 2,
"cast.result");
380 PHI->addIncoming(
Value.emitRawPointer(*
this), notNullBB);
381 PHI->addIncoming(llvm::Constant::getNullValue(PtrTy), origBB);
392 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
395 llvm::Type *DerivedValueTy =
ConvertType(DerivedTy);
397 llvm::Value *NonVirtualOffset =
398 CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd);
400 if (!NonVirtualOffset) {
405 llvm::BasicBlock *CastNull =
nullptr;
406 llvm::BasicBlock *CastNotNull =
nullptr;
407 llvm::BasicBlock *CastEnd =
nullptr;
409 if (NullCheckValue) {
423 CGM.getClassPointerAlignment(Derived),
"sub.ptr");
426 Addr =
Addr.withElementType(DerivedValueTy);
429 if (NullCheckValue) {
435 llvm::Value *
Value =
Addr.emitRawPointer(*
this);
437 PHI->addIncoming(
Value, CastNotNull);
438 PHI->addIncoming(llvm::Constant::getNullValue(
Value->
getType()), CastNull);
440 CGM.getClassPointerAlignment(Derived));
449 if (!
CGM.getCXXABI().NeedsVTTParameter(GD)) {
457 uint64_t SubVTTIndex;
462 }
else if (RD ==
Base) {
465 assert(!
CGM.getCXXABI().NeedsVTTParameter(
CurGD) &&
466 "doing no-op VTT offset in base dtor/ctor?");
467 assert(!ForVirtualBase &&
"Can't have same class as virtual base!");
476 assert(SubVTTIndex != 0 &&
"Sub-VTT index must be greater than zero!");
480 if (
CGM.getCXXABI().NeedsVTTParameter(
CurGD)) {
485 VTT =
CGM.getVTables().GetAddrOfVTT(RD);
487 return Builder.CreateConstInBoundsGEP1_64(
CGM.GlobalsInt8PtrTy, VTT,
493struct CallBaseDtor final : EHScopeStack::Cleanup {
497 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
510 false,
Addr, ThisTy);
516struct DynamicThisUseChecker
517 : ConstEvaluatedExprVisitor<DynamicThisUseChecker> {
518 typedef ConstEvaluatedExprVisitor<DynamicThisUseChecker> super;
522 DynamicThisUseChecker(
const ASTContext &
C) : super(
C), UsesThis(
false) {}
529 void VisitCXXThisExpr(
const CXXThisExpr *E) { UsesThis =
true; }
534 DynamicThisUseChecker Checker(
C);
536 return Checker.UsesThis;
559 ThisPtr, ClassDecl, BaseClassDecl, isBaseVirtual);
568 !BaseClassDecl->hasTrivialDestructor())
575 auto *CD = dyn_cast<CXXConstructorDecl>(D);
576 if (!(CD && CD->isCopyOrMoveConstructor()) &&
606 for (
const auto *I : IndirectField->
chain())
621 "Must have member initializer!");
622 assert(MemberInit->
getInit() &&
"Must have initializer!");
626 QualType FieldType = Field->getType();
655 unsigned SrcArgIndex =
657 llvm::Value *SrcPtr =
665 LHS.isVolatileQualified());
680 QualType FieldType = Field->getType();
772 struct SizeAndOffset {
777 unsigned PtrSize =
CGM.getDataLayout().getPointerSizeInBits();
784 Context.toCharUnitsFromBits(Info.
getFieldOffset(i)).getQuantity();
786 size_t NumFields = 0;
787 for (
const auto *Field : ClassDecl->
fields()) {
789 auto FieldInfo = Context.getTypeInfoInChars(D->
getType());
791 assert(NumFields < SSV.size());
795 assert(NumFields == SSV.size());
802 llvm::FunctionType *FTy = llvm::FunctionType::get(
CGM.VoidTy, Args,
false);
803 llvm::FunctionCallee F =
CGM.CreateRuntimeFunction(
804 FTy, Prologue ?
"__asan_poison_intra_object_redzone"
805 :
"__asan_unpoison_intra_object_redzone");
812 for (
size_t i = 0; i < SSV.size(); i++) {
813 uint64_t AsanAlignment = 8;
814 uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
815 uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
816 uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
817 if (PoisonSize < AsanAlignment || !SSV[i].Size ||
818 (NextField % AsanAlignment) != 0)
821 F, {
Builder.CreateAdd(ThisPtr,
Builder.getIntN(PtrSize, EndOffset)),
822 Builder.getIntN(PtrSize, PoisonSize)});
832 assert((
CGM.getTarget().getCXXABI().hasConstructorVariants() ||
834 "can only generate complete ctor for this ABI");
839 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
846 assert(
Definition == Ctor &&
"emitting wrong constructor body");
850 bool IsTryBody = isa_and_nonnull<CXXTryStmt>(Body);
887class CopyingValueRepresentation {
890 : CGF(CGF), OldSanOpts(CGF.SanOpts) {
894 ~CopyingValueRepresentation() { CGF.
SanOpts = OldSanOpts; }
903class FieldMemcpyizer {
905 FieldMemcpyizer(CodeGenFunction &CGF,
const CXXRecordDecl *ClassDecl,
906 const VarDecl *SrcRec)
907 : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
908 RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
910 LastFieldOffset(0), LastAddedFieldIndex(0) {}
912 bool isMemcpyableField(FieldDecl *F)
const {
930 void addMemcpyableField(FieldDecl *F) {
939 CharUnits getMemcpySize(uint64_t FirstByteOffset)
const {
941 unsigned LastFieldSize =
942 LastField->isBitField()
943 ? LastField->getBitWidthValue()
946 uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize -
960 if (FirstField->isBitField()) {
961 const CGRecordLayout &RL =
968 FirstByteOffset = FirstFieldOffset;
971 CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
980 emitMemcpyIR(Dest.isBitField() ? Dest.getBitFieldAddress()
982 Src.isBitField() ? Src.getBitFieldAddress() : Src.getAddress(),
987 void reset() { FirstField =
nullptr; }
990 CodeGenFunction &CGF;
991 const CXXRecordDecl *ClassDecl;
994 void emitMemcpyIR(Address DestPtr, Address SrcPtr, CharUnits Size) {
1001 void addInitialField(FieldDecl *F) {
1004 FirstFieldOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
1005 LastFieldOffset = FirstFieldOffset;
1009 void addNextField(FieldDecl *F) {
1015 "Cannot aggregate fields out of order.");
1022 if (FOffset < FirstFieldOffset) {
1024 FirstFieldOffset = FOffset;
1025 }
else if (FOffset >= LastFieldOffset) {
1027 LastFieldOffset = FOffset;
1031 const VarDecl *SrcRec;
1032 const ASTRecordLayout &RecLayout;
1033 FieldDecl *FirstField;
1034 FieldDecl *LastField;
1035 uint64_t FirstFieldOffset, LastFieldOffset;
1036 unsigned LastAddedFieldIndex;
1039class ConstructorMemcpyizer :
public FieldMemcpyizer {
1043 static const VarDecl *getTrivialCopySource(CodeGenFunction &CGF,
1044 const CXXConstructorDecl *CD,
1045 FunctionArgList &Args) {
1053 bool isMemberInitMemcpyable(CXXCtorInitializer *MemberInit)
const {
1054 if (!MemcpyableCtor)
1057 assert(Field &&
"No field for member init.");
1058 QualType FieldType =
Field->getType();
1059 CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(MemberInit->
getInit());
1069 if (!isMemcpyableField(Field))
1077 ConstructorMemcpyizer(CodeGenFunction &CGF,
const CXXConstructorDecl *CD,
1078 FunctionArgList &Args)
1079 : FieldMemcpyizer(CGF, CD->getParent(),
1080 getTrivialCopySource(CGF, CD, Args)),
1081 ConstructorDecl(CD),
1082 MemcpyableCtor(CD->isDefaulted() && CD->isCopyOrMoveConstructor() &&
1083 CGF.getLangOpts().getGC() == LangOptions::NonGC),
1086 void addMemberInitializer(CXXCtorInitializer *MemberInit) {
1087 if (isMemberInitMemcpyable(MemberInit)) {
1088 AggregatedInits.push_back(MemberInit);
1089 addMemcpyableField(MemberInit->
getMember());
1091 emitAggregatedInits();
1093 ConstructorDecl, Args);
1097 void emitAggregatedInits() {
1098 if (AggregatedInits.size() <= 1) {
1101 if (!AggregatedInits.empty()) {
1102 CopyingValueRepresentation CVR(CGF);
1104 AggregatedInits[0], ConstructorDecl, Args);
1105 AggregatedInits.clear();
1111 pushEHDestructors();
1114 AggregatedInits.clear();
1117 void pushEHDestructors() {
1122 for (
unsigned i = 0; i < AggregatedInits.size(); ++i) {
1123 CXXCtorInitializer *MemberInit = AggregatedInits[i];
1128 LValue FieldLHS = LHS;
1130 CGF.
pushEHDestroy(dtorKind, FieldLHS.getAddress(), FieldType);
1134 void finish() { emitAggregatedInits(); }
1137 const CXXConstructorDecl *ConstructorDecl;
1138 bool MemcpyableCtor;
1139 FunctionArgList &Args;
1140 SmallVector<CXXCtorInitializer *, 16> AggregatedInits;
1143class AssignmentMemcpyizer :
public FieldMemcpyizer {
1147 FieldDecl *getMemcpyableField(Stmt *S) {
1148 if (!AssignmentsMemcpyable)
1150 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(S)) {
1152 if (BO->getOpcode() != BO_Assign)
1154 MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS());
1158 if (!Field || !isMemcpyableField(Field))
1160 Stmt *RHS = BO->getRHS();
1161 if (ImplicitCastExpr *EC = dyn_cast<ImplicitCastExpr>(RHS))
1162 RHS = EC->getSubExpr();
1165 if (MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
1166 if (ME2->getMemberDecl() == Field)
1170 }
else if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(S)) {
1171 CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
1174 MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument());
1178 if (!Field || !isMemcpyableField(Field))
1180 MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0));
1181 if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->
getMemberDecl()))
1184 }
else if (CallExpr *CE = dyn_cast<CallExpr>(S)) {
1185 FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1186 if (!FD || FD->
getBuiltinID() != Builtin::BI__builtin_memcpy)
1188 Expr *DstPtr = CE->
getArg(0);
1189 if (ImplicitCastExpr *DC = dyn_cast<ImplicitCastExpr>(DstPtr))
1190 DstPtr = DC->getSubExpr();
1191 UnaryOperator *DUO = dyn_cast<UnaryOperator>(DstPtr);
1192 if (!DUO || DUO->
getOpcode() != UO_AddrOf)
1194 MemberExpr *ME = dyn_cast<MemberExpr>(DUO->
getSubExpr());
1198 if (!Field || !isMemcpyableField(Field))
1200 Expr *SrcPtr = CE->
getArg(1);
1201 if (ImplicitCastExpr *SC = dyn_cast<ImplicitCastExpr>(SrcPtr))
1202 SrcPtr = SC->getSubExpr();
1203 UnaryOperator *SUO = dyn_cast<UnaryOperator>(SrcPtr);
1204 if (!SUO || SUO->
getOpcode() != UO_AddrOf)
1206 MemberExpr *ME2 = dyn_cast<MemberExpr>(SUO->
getSubExpr());
1207 if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->
getMemberDecl()))
1215 bool AssignmentsMemcpyable;
1216 SmallVector<Stmt *, 16> AggregatedStmts;
1219 AssignmentMemcpyizer(CodeGenFunction &CGF,
const CXXMethodDecl *AD,
1220 FunctionArgList &Args)
1221 : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]),
1222 AssignmentsMemcpyable(CGF.getLangOpts().getGC() == LangOptions::NonGC) {
1223 assert(Args.size() == 2);
1226 void emitAssignment(Stmt *S) {
1227 FieldDecl *F = getMemcpyableField(S);
1229 addMemcpyableField(F);
1230 AggregatedStmts.push_back(S);
1232 emitAggregatedStmts();
1237 void emitAggregatedStmts() {
1238 if (AggregatedStmts.size() <= 1) {
1239 if (!AggregatedStmts.empty()) {
1240 CopyingValueRepresentation CVR(CGF);
1248 AggregatedStmts.clear();
1251 void finish() { emitAggregatedStmts(); }
1278 bool ConstructVBases = CtorType !=
Ctor_Base &&
1285 llvm::BasicBlock *BaseCtorContinueBB =
nullptr;
1286 if (ConstructVBases &&
1287 !
CGM.getTarget().getCXXABI().hasConstructorVariants()) {
1288 BaseCtorContinueBB =
1289 CGM.getCXXABI().EmitCtorCompleteObjectHandler(*
this, ClassDecl);
1290 assert(BaseCtorContinueBB);
1294 auto AllInits = CD->
inits();
1297 auto VirtualBaseEnd = std::find_if(
1299 return !(Init->isBaseInitializer() && Init->isBaseVirtual());
1302 auto NonVirtualBaseEnd = std::find_if(VirtualBaseEnd, AllInits.end(),
1304 return !Init->isBaseInitializer();
1308 auto VirtualBaseInits = llvm::make_range(AllInits.begin(), VirtualBaseEnd);
1309 auto NonVirtualBaseInits =
1310 llvm::make_range(VirtualBaseEnd, NonVirtualBaseEnd);
1311 auto MemberInits = llvm::make_range(NonVirtualBaseEnd, AllInits.end());
1314 if (ConstructVBases) {
1317 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1318 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1325 if (BaseCtorContinueBB) {
1327 Builder.CreateBr(BaseCtorContinueBB);
1335 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1336 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1346 ConstructorMemcpyizer CM(*
this, CD, Args);
1348 assert(!
Member->isBaseInitializer());
1349 assert(
Member->isAnyMemberInitializer() &&
1350 "Delegating initializer on non-delegating constructor");
1351 CM.addMemberInitializer(
Member);
1372 for (
const auto *Field : BaseClassDecl->
fields())
1377 for (
const auto &I : BaseClassDecl->
bases()) {
1383 MostDerivedClassDecl))
1387 if (BaseClassDecl == MostDerivedClassDecl) {
1389 for (
const auto &I : BaseClassDecl->
vbases()) {
1390 const auto *
VirtualBase = I.getType()->castAsCXXRecordDecl();
1401 QualType FieldBaseElementType = Context.getBaseElementType(Field->getType());
1404 if (!FieldClassDecl)
1408 if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
1431 for (
const auto *Field : ClassDecl->
fields())
1440 llvm::Value *ShouldDeleteCondition) {
1443 llvm::BasicBlock *callDeleteBB =
1447 llvm::Value *CheckTheBitForArrayDestroy = CGF.
Builder.CreateAnd(
1448 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 2));
1449 llvm::Value *ShouldDestroyArray =
1451 CGF.
Builder.CreateCondBr(ShouldDestroyArray, ScalarBB, VectorBB);
1455 llvm::Value *numElements =
nullptr;
1456 llvm::Value *allocatedPtr =
nullptr;
1460 allocatedPtr, cookieSize);
1466 assert(numElements &&
"no element count for a type with a destructor!");
1474 ThisPtr.
getElementType(), arrayBegin, numElements,
"delete.end");
1485 llvm::Value *CheckTheBitForDeleteCall = CGF.
Builder.CreateAnd(
1486 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
1488 llvm::Value *ShouldCallDelete =
1499 numElements, cookieSize);
1504 llvm::Value *CheckTheBitForGlobDeleteCall = CGF.
Builder.CreateAnd(
1505 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
1507 llvm::Value *ShouldCallGlobDelete =
1509 llvm::BasicBlock *GlobDelete =
1511 llvm::BasicBlock *ClassDelete =
1513 CGF.
Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
1517 numElements, cookieSize);
1523 numElements, cookieSize);
1527 llvm::CallInst *TrapCall = CGF.
EmitTrapCall(llvm::Intrinsic::trap);
1528 TrapCall->setDoesNotReturn();
1529 TrapCall->setDoesNotThrow();
1530 CGF.
Builder.CreateUnreachable();
1531 CGF.
Builder.ClearInsertionPoint();
1549 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
1550 TrapCall->setDoesNotReturn();
1551 TrapCall->setDoesNotThrow();
1553 Builder.ClearInsertionPoint();
1582 bool isTryBody = isa_and_nonnull<CXXTryStmt>(Body);
1597 llvm_unreachable(
"not expecting a unified dtor");
1599 llvm_unreachable(
"not expecting a COMDAT");
1601 llvm_unreachable(
"already handled deleting case");
1603 llvm_unreachable(
"already handled vector deleting case");
1606 assert((Body ||
getTarget().getCXXABI().isMicrosoft()) &&
1607 "can't emit a dtor without a body for non-Microsoft ABIs");
1632 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
1633 CGM.getCodeGenOpts().OptimizationLevel > 0)
1643 assert(Dtor->
isImplicit() &&
"bodyless dtor not implicit");
1649 CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
1667 "Body of an implicit assignment operator should be compound stmt.");
1674 AssignmentMemcpyizer AM(*
this, AssignOp, Args);
1675 for (
auto *I : RootCS->
body())
1676 AM.emitAssignment(I);
1690struct CallDtorDelete final : EHScopeStack::Cleanup {
1697 LoadThisForDtorDelete(CGF, Dtor),
1708 llvm::Value *ShouldDeleteCondition,
1709 bool ReturnAfterDelete) {
1711 const CXXRecordDecl *ClassDecl = Dtor->
getParent();
1714 "unexpected value for ReturnAfterDelete");
1729 llvm::Value *Check3rdBit = CGF.
Builder.CreateAnd(
1730 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
1732 CGF.
Builder.CreateCondBr(ShouldCallDtor, DontCallDtor, CallDtor);
1738 CGF.
Builder.CreateBr(DontCallDtor);
1744 llvm::Value *Check1stBit = CGF.
Builder.CreateAnd(
1745 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 1));
1747 CGF.
Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
1750 auto EmitDeleteAndGoToEnd = [&](
const FunctionDecl *DeleteOp) {
1753 if (ReturnAfterDelete)
1756 CGF.
Builder.CreateBr(continueBB);
1765 llvm::Value *CheckTheBitForGlobDeleteCall = CGF.
Builder.CreateAnd(
1766 ShouldDeleteCondition, llvm::ConstantInt::get(CondTy, 4));
1767 llvm::Value *ShouldCallGlobDelete =
1769 llvm::BasicBlock *GlobDelete =
1771 llvm::BasicBlock *ClassDelete =
1773 CGF.
Builder.CreateCondBr(ShouldCallGlobDelete, ClassDelete, GlobDelete);
1776 EmitDeleteAndGoToEnd(GlobOD);
1779 EmitDeleteAndGoToEnd(OD);
1783struct CallDtorDeleteConditional final : EHScopeStack::Cleanup {
1784 llvm::Value *ShouldDeleteCondition;
1787 CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition)
1788 : ShouldDeleteCondition(ShouldDeleteCondition) {
1789 assert(ShouldDeleteCondition !=
nullptr);
1792 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1793 EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition,
1798class DestroyField final :
public EHScopeStack::Cleanup {
1799 const FieldDecl *field;
1801 bool useEHCleanupForArray;
1805 bool useEHCleanupForArray)
1806 : field(field), destroyer(destroyer),
1807 useEHCleanupForArray(useEHCleanupForArray) {}
1809 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1816 assert(LV.isSimple());
1818 CGF.
emitDestroy(LV.getAddress(), field->getType(), destroyer,
1819 flags.isForNormalCleanup() && useEHCleanupForArray);
1823class DeclAsInlineDebugLocation {
1825 llvm::MDNode *InlinedAt;
1826 std::optional<ApplyDebugLocation> Location;
1829 DeclAsInlineDebugLocation(CodeGenFunction &CGF,
const NamedDecl &
Decl)
1830 : DI(CGF.getDebugInfo()) {
1835 Location.emplace(CGF,
Decl.getLocation());
1838 ~DeclAsInlineDebugLocation() {
1846static void EmitSanitizerDtorCallback(
1848 std::optional<CharUnits::QuantityType> PoisonSize = {}) {
1852 SmallVector<llvm::Value *, 2> Args = {Ptr};
1853 SmallVector<llvm::Type *, 2> ArgTypes = {CGF.
VoidPtrTy};
1855 if (PoisonSize.has_value()) {
1856 Args.emplace_back(llvm::ConstantInt::get(CGF.
SizeTy, *PoisonSize));
1857 ArgTypes.emplace_back(CGF.
SizeTy);
1860 llvm::FunctionType *FnType =
1861 llvm::FunctionType::get(CGF.
VoidTy, ArgTypes,
false);
1868EmitSanitizerDtorFieldsCallback(
CodeGenFunction &CGF, llvm::Value *Ptr,
1870 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_fields", Ptr,
1875struct SanitizeDtorTrivialBase final : EHScopeStack::Cleanup {
1876 const CXXRecordDecl *BaseClass;
1878 SanitizeDtorTrivialBase(
const CXXRecordDecl *Base,
bool BaseIsVirtual)
1879 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
1881 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1882 const CXXRecordDecl *DerivedClass =
1888 const ASTRecordLayout &BaseLayout =
1890 CharUnits BaseSize = BaseLayout.
getSize();
1897 DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass);
1898 EmitSanitizerDtorFieldsCallback(CGF,
Addr.emitRawPointer(CGF),
1902 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1906class SanitizeDtorFieldRange final :
public EHScopeStack::Cleanup {
1907 const CXXDestructorDecl *Dtor;
1908 unsigned StartIndex;
1912 SanitizeDtorFieldRange(
const CXXDestructorDecl *Dtor,
unsigned StartIndex,
1914 : Dtor(Dtor), StartIndex(StartIndex), EndIndex(EndIndex) {}
1919 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1920 const ASTContext &Context = CGF.
getContext();
1921 const ASTRecordLayout &Layout =
1928 llvm::ConstantInt *OffsetSizePtr =
1931 llvm::Value *OffsetPtr =
1934 CharUnits PoisonEnd;
1940 CharUnits PoisonSize = PoisonEnd - PoisonStart;
1945 DeclAsInlineDebugLocation InlineHere(
1946 CGF, **std::next(Dtor->getParent()->field_begin(), StartIndex));
1947 EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.
getQuantity());
1950 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1954class SanitizeDtorVTable final :
public EHScopeStack::Cleanup {
1955 const CXXDestructorDecl *Dtor;
1958 SanitizeDtorVTable(
const CXXDestructorDecl *Dtor) : Dtor(Dtor) {}
1961 void Emit(CodeGenFunction &CGF, Flags flags)
override {
1962 assert(Dtor->getParent()->isDynamicClass());
1969 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_vptr", VTablePtr);
1973class SanitizeDtorCleanupBuilder {
1974 ASTContext &Context;
1975 EHScopeStack &EHStack;
1976 const CXXDestructorDecl *DD;
1977 std::optional<unsigned> StartIndex;
1980 SanitizeDtorCleanupBuilder(ASTContext &Context, EHScopeStack &EHStack,
1981 const CXXDestructorDecl *DD)
1982 : Context(Context), EHStack(EHStack), DD(DD), StartIndex(std::nullopt) {}
1983 void PushCleanupForField(
const FieldDecl *Field) {
1986 unsigned FieldIndex =
Field->getFieldIndex();
1989 StartIndex = FieldIndex;
1990 }
else if (StartIndex) {
1992 *StartIndex, FieldIndex);
1993 StartIndex = std::nullopt;
2013 "Should not emit dtor epilogue for non-exported trivial dtor!");
2019 "operator delete missing - EnterDtorCleanups");
2020 if (CXXStructorImplicitParamValue) {
2024 EmitConditionalDtorDeleteCall(*
this, CXXStructorImplicitParamValue,
2027 EHStack.pushCleanup<CallDtorDeleteConditional>(
2033 LoadThisForDtorDelete(*
this, DD),
2034 getContext().getCanonicalTagType(ClassDecl));
2053 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2060 for (
const auto &
Base : ClassDecl->
vbases()) {
2061 auto *BaseClassDecl =
Base.getType()->castAsCXXRecordDecl();
2062 if (BaseClassDecl->hasTrivialDestructor()) {
2066 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2067 SanOpts.has(SanitizerKind::Memory) && !BaseClassDecl->isEmpty())
2083 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2089 for (
const auto &
Base : ClassDecl->
bases()) {
2091 if (
Base.isVirtual())
2097 if (
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2110 bool SanitizeFields =
CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
2111 SanOpts.has(SanitizerKind::Memory);
2115 for (
const auto *Field : ClassDecl->
fields()) {
2117 SanitizeBuilder.PushCleanupForField(Field);
2125 const RecordType *RT =
type->getAsUnionType();
2126 if (RT && RT->getDecl()->isAnonymousStructOrUnion())
2130 EHStack.pushCleanup<DestroyField>(
2135 SanitizeBuilder.End();
2150 bool NewPointerIsChecked,
2151 bool zeroInitialize) {
2153 llvm::Value *numElements =
2157 NewPointerIsChecked, zeroInitialize);
2171 const CXXConstructExpr *E,
bool NewPointerIsChecked,
bool zeroInitialize) {
2177 llvm::BranchInst *zeroCheckBranch =
nullptr;
2180 llvm::ConstantInt *constantCount = dyn_cast<llvm::ConstantInt>(numElements);
2181 if (constantCount) {
2183 if (constantCount->isZero())
2189 llvm::Value *iszero =
Builder.CreateIsNull(numElements,
"isempty");
2190 zeroCheckBranch =
Builder.CreateCondBr(iszero, loopBB, loopBB);
2197 llvm::Value *arrayEnd =
Builder.CreateInBoundsGEP(
2198 elementType, arrayBegin, numElements,
"arrayctor.end");
2201 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
2204 llvm::PHINode *cur =
2205 Builder.CreatePHI(arrayBegin->getType(), 2,
"arrayctor.cur");
2206 cur->addIncoming(arrayBegin, entryBB);
2209 if (
CGM.shouldEmitConvergenceTokens())
2257 llvm::Value *next =
Builder.CreateInBoundsGEP(
2258 elementType, cur, llvm::ConstantInt::get(
SizeTy, 1),
"arrayctor.next");
2259 cur->addIncoming(next,
Builder.GetInsertBlock());
2262 llvm::Value *done =
Builder.CreateICmpEQ(next, arrayEnd,
"arrayctor.done");
2264 Builder.CreateCondBr(done, contBB, loopBB);
2267 if (zeroCheckBranch)
2268 zeroCheckBranch->setSuccessor(0, contBB);
2270 if (
CGM.shouldEmitConvergenceTokens())
2291 llvm::Value *ThisPtr =
2294 if (SlotAS != ThisAS) {
2296 llvm::Type *NewType =
2308 assert(E->
getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
2359 bool NewPointerIsChecked, llvm::CallBase **CallOrInvoke) {
2362 if (!NewPointerIsChecked)
2368 assert(Args.size() == 1 &&
"trivial default ctor with args");
2376 assert(Args.size() == 2 &&
"unexpected argcount for trivial ctor");
2379 Args[1].getRValue(*this).getScalarVal(), SrcTy);
2387 bool PassPrototypeArgs =
true;
2400 CGM.getCXXABI().addImplicitConstructorArgs(*
this, D,
Type, ForVirtualBase,
2422 if (
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2424 CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) &&
2425 CGM.getCodeGenOpts().StrictVTablePointers)
2438 if (InheritedFromVBase &&
2439 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
2444 Args.push_back(ThisArg);
2445 }
else if (!CXXInheritedCtorInitExprArgs.empty()) {
2447 assert(CXXInheritedCtorInitExprArgs.size() >= D->
getNumParams() &&
2448 "wrong number of parameters for inherited constructor call");
2449 Args = CXXInheritedCtorInitExprArgs;
2453 Args.push_back(ThisArg);
2455 assert(OuterCtor->getNumParams() == D->
getNumParams());
2456 assert(!OuterCtor->isVariadic() &&
"should have been inlined");
2458 for (
const auto *Param : OuterCtor->parameters()) {
2460 OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
2465 if (Param->hasAttr<PassObjectSizeAttr>()) {
2466 auto *POSParam = SizeArguments[Param];
2467 assert(POSParam &&
"missing pass_object_size value for forwarding");
2487 CXXInheritedCtorInitExprArgs = Args;
2494 CGM.getCXXABI().addImplicitConstructorArgs(*
this, Ctor, CtorType,
2498 assert(Args.size() >= Params.size() &&
"too few arguments for call");
2499 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
2501 const RValue &RV = Args[I].getRValue(*
this);
2502 assert(!RV.
isComplex() &&
"complex indirect params not supported");
2516 CGM.getCXXABI().EmitInstanceFunctionProlog(*
this);
2517 CXXThisValue = CXXABIThisValue;
2524 llvm::Value *VTableGlobal =
2532 if (!NonVirtualOffset.
isZero())
2537 llvm::Value *VPtrValue =
2540 Builder.CreateICmpEQ(VPtrValue, VTableGlobal,
"cmp.vtables");
2546 if (
CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))
2564 llvm::Type *t =
CGM.getTypes().ConvertType(QT);
2566 llvm::Value *SrcVal =
Builder.CreateBitCast(Val, t);
2584 FunctionArgList::const_iterator I = Args.begin(), E = Args.end();
2585 assert(I != E &&
"no parameters to constructor");
2590 This, (*I)->getType()->getPointeeType())),
2596 if (
CGM.getCXXABI().NeedsVTTParameter(
CurGD)) {
2597 assert(I != E &&
"cannot skip vtt parameter, already done with args");
2598 assert((*I)->getType()->isPointerType() &&
2599 "skipping parameter not of vtt type");
2604 for (; I != E; ++I) {
2611 true,
This, DelegateArgs,
2617struct CallDelegatingCtorDtor final : EHScopeStack::Cleanup {
2629 QualType ThisTy = Dtor->getFunctionObjectParameterType();
2631 true,
Addr, ThisTy);
2656 EHStack.pushCleanup<CallDelegatingCtorDtor>(
2663 bool ForVirtualBase,
2666 CGM.getCXXABI().EmitDestructorCall(*
this, DD,
Type, ForVirtualBase,
2671struct CallLocalDtor final : EHScopeStack::Cleanup {
2700 assert(D && D->
isUsed() &&
"destructor not marked as used!");
2706 llvm::Value *VTableAddressPoint =
2707 CGM.getCXXABI().getVTableAddressPointInStructor(
2710 if (!VTableAddressPoint)
2714 llvm::Value *VirtualOffset =
nullptr;
2717 if (
CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*
this, Vptr)) {
2721 VirtualOffset =
CGM.getCXXABI().GetVirtualBaseClassOffset(
2731 if (!NonVirtualOffset.
isZero() || VirtualOffset)
2733 *
this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.
VTableClass,
2738 unsigned GlobalsAS =
CGM.getDataLayout().getDefaultGlobalsAddressSpace();
2739 llvm::Type *PtrTy = llvm::PointerType::get(
CGM.getLLVMContext(), GlobalsAS);
2744 if (
auto AuthenticationInfo =
CGM.getVTablePointerAuthInfo(
2746 VTableAddressPoint =
2749 llvm::StoreInst *Store =
Builder.CreateStore(VTableAddressPoint, VTableField);
2751 CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
2752 if (
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2753 CGM.getCodeGenOpts().StrictVTablePointers)
2754 CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.
VTableClass);
2764 false, VTableClass, VBases,
2772 bool BaseIsNonVirtualPrimaryBase,
2778 if (!BaseIsNonVirtualPrimaryBase) {
2780 VPtr Vptr = {
Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
2781 Vptrs.push_back(Vptr);
2787 for (
const auto &I : RD->
bases()) {
2788 auto *BaseDecl = I.getType()->castAsCXXRecordDecl();
2790 if (!BaseDecl->isDynamicClass())
2795 bool BaseDeclIsNonVirtualPrimaryBase;
2797 if (I.isVirtual()) {
2799 if (!VBases.insert(BaseDecl).second)
2807 BaseDeclIsNonVirtualPrimaryBase =
false;
2812 BaseOffsetFromNearestVBase =
2814 BaseDeclIsNonVirtualPrimaryBase = Layout.
getPrimaryBase() == BaseDecl;
2819 I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
2820 BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
2830 if (
CGM.getCXXABI().doStructorsInitializeVPtrs(RD))
2835 CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*
this, RD);
2841 Address VTablePtrSrc =
This.withElementType(VTableTy);
2842 llvm::Instruction *VTable =
Builder.CreateLoad(VTablePtrSrc,
"vtable");
2844 CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo);
2846 if (
auto AuthenticationInfo =
2847 CGM.getVTablePointerAuthInfo(
this, RD,
This.emitRawPointer(*
this))) {
2868 if (
CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2869 CGM.getCodeGenOpts().StrictVTablePointers)
2870 CGM.DecorateInstructionWithInvariantGroup(VTable, RD);
2911 llvm::Value *VTable,
2913 if (
SanOpts.has(SanitizerKind::CFIVCall))
2921 else if ((
CGM.getCodeGenOpts().WholeProgramVTables &&
2922 !
CGM.AlwaysHasLTOVisibilityPublic(RD)) ||
2923 CGM.getCodeGenOpts().DevirtualizeSpeculatively) {
2925 llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(Ty);
2926 llvm::Value *TypeId = llvm::MetadataAsValue::get(
CGM.getLLVMContext(), MD);
2932 llvm::Intrinsic::ID IID =
CGM.HasHiddenLTOVisibility(RD)
2933 ? llvm::Intrinsic::type_test
2934 : llvm::Intrinsic::public_type_test;
2935 llvm::Value *TypeTest =
2936 Builder.CreateCall(
CGM.getIntrinsic(IID), {VTable, TypeId});
2937 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
2943static std::pair<SanitizerKind::SanitizerOrdinal, llvm::SanitizerStatKind>
2947 return std::make_pair(SanitizerKind::SO_CFIVCall, llvm::SanStat_CFI_VCall);
2949 return std::make_pair(SanitizerKind::SO_CFINVCall,
2950 llvm::SanStat_CFI_NVCall);
2952 return std::make_pair(SanitizerKind::SO_CFIDerivedCast,
2953 llvm::SanStat_CFI_DerivedCast);
2955 return std::make_pair(SanitizerKind::SO_CFIUnrelatedCast,
2956 llvm::SanStat_CFI_UnrelatedCast);
2960 llvm_unreachable(
"unexpected sanitizer kind");
2962 llvm_unreachable(
"Unknown CFITypeCheckKind enum");
2966 llvm::Value *VTable,
2969 if (!
SanOpts.has(SanitizerKind::CFICastStrict))
2974 SanitizerHandler::CFICheckFail);
2986 const auto *ClassDecl = T->getAsCXXRecordDecl();
2993 if (!
SanOpts.has(SanitizerKind::CFICastStrict))
2998 SanitizerHandler::CFICheckFail);
3000 llvm::BasicBlock *ContBlock =
nullptr;
3003 llvm::Value *DerivedNotNull =
3009 Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
3014 llvm::Value *VTable;
3015 std::tie(VTable, ClassDecl) =
3016 CGM.getCXXABI().LoadVTablePtr(*
this, Derived, ClassDecl);
3027 llvm::Value *VTable,
3032 if (!
CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
3033 !
CGM.HasHiddenLTOVisibility(RD))
3039 if (
getContext().getNoSanitizeList().containsType(
3046 llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(T);
3047 llvm::Value *TypeId = llvm::MetadataAsValue::get(
getLLVMContext(), MD);
3049 llvm::Value *TypeTest =
Builder.CreateCall(
3050 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, TypeId});
3052 llvm::Constant *StaticData[] = {
3053 llvm::ConstantInt::get(
Int8Ty, TCK),
3058 auto CrossDsoTypeId =
CGM.CreateCrossDsoCfiTypeId(MD);
3059 if (
CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
3064 if (
CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
3065 bool NoMerge = !
CGM.getCodeGenOpts().SanitizeMergeHandlers.has(M);
3066 EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail, NoMerge);
3070 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
3071 CGM.getLLVMContext(),
3072 llvm::MDString::get(
CGM.getLLVMContext(),
"all-vtables"));
3073 llvm::Value *ValidVtable =
Builder.CreateCall(
3074 CGM.getIntrinsic(llvm::Intrinsic::type_test), {VTable, AllVtables});
3075 EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
3076 StaticData, {VTable, ValidVtable});
3080 if ((!
CGM.getCodeGenOpts().WholeProgramVTables ||
3081 !
CGM.HasHiddenLTOVisibility(RD)) &&
3082 !
CGM.getCodeGenOpts().DevirtualizeSpeculatively)
3085 if (
CGM.getCodeGenOpts().VirtualFunctionElimination)
3088 if (!
SanOpts.has(SanitizerKind::CFIVCall) ||
3089 !
CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall))
3098 const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy,
3099 uint64_t VTableByteOffset) {
3100 auto CheckOrdinal = SanitizerKind::SO_CFIVCall;
3101 auto CheckHandler = SanitizerHandler::CFICheckFail;
3107 llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(T);
3108 llvm::Value *TypeId = llvm::MetadataAsValue::get(
CGM.getLLVMContext(), MD);
3110 auto CheckedLoadIntrinsic =
CGM.getVTables().useRelativeLayout()
3111 ? llvm::Intrinsic::type_checked_load_relative
3112 : llvm::Intrinsic::type_checked_load;
3113 llvm::Value *CheckedLoad =
Builder.CreateCall(
3114 CGM.getIntrinsic(CheckedLoadIntrinsic),
3115 {VTable, llvm::ConstantInt::get(Int32Ty, VTableByteOffset), TypeId});
3117 llvm::Value *CheckResult =
Builder.CreateExtractValue(CheckedLoad, 1);
3120 if (
SanOpts.has(SanitizerKind::CFIVCall) &&
3121 !
getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
3123 EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler, {}, {});
3126 return Builder.CreateBitCast(
Builder.CreateExtractValue(CheckedLoad, 0),
3135 calleeFnInfo = &
CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
3140 CGM.getTypes().GetFunctionType(*calleeFnInfo));
3147 if (!resultType->isVoidType() &&
3160 RValue RV =
EmitCall(*calleeFnInfo, callee, returnSlot, callArgs);
3163 if (!resultType->isVoidType() && returnSlot.
isNull()) {
3164 if (
getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
3167 EmitReturnOfRValue(RV, resultType);
3178 if (CallOp->isVariadic()) {
3182 CGM.ErrorUnsupported(
CurCodeDecl,
"lambda conversion to variadic function");
3199 "generic lambda interconversion to block not implemented");
3208 CGM.ErrorUnsupported(MD,
"lambda conversion to variadic function");
3239 CallOp->getDescribedFunctionTemplate();
3240 void *InsertPos =
nullptr;
3243 assert(CorrespondingCallOpSpecialization);
3248 if (hasInAllocaArg(MD)) {
3250 llvm::Function *ImplFn =
nullptr;
3265 CGM.ErrorUnsupported(MD,
"lambda conversion to variadic function");
3273 llvm::Value *ThisArg =
CurFn->getArg(0);
3281 llvm::Function **ImplFn) {
3283 CGM.getTypes().arrangeCXXMethodDeclaration(CallOp);
3284 llvm::Function *CallOpFn =
3291 ArgTypes.push_back(I->type);
3292 *ImplFnInfo = &
CGM.getTypes().arrangeLLVMFunctionInfo(
3301 StringRef CallOpName = CallOpFn->getName();
3302 std::string ImplName;
3303 if (
size_t Pos = CallOpName.find_first_of(
"<lambda"))
3304 ImplName = (
"?__impl@" + CallOpName.drop_front(Pos)).str();
3306 ImplName = (
"__impl" + CallOpName).str();
3308 llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName);
3310 Fn = llvm::Function::Create(
CGM.getTypes().GetFunctionType(**ImplFnInfo),
3311 llvm::GlobalValue::InternalLinkage, ImplName,
3313 CGM.SetInternalFunctionAttributes(CallOp, Fn, **ImplFnInfo);
3317 CodeGenFunction(
CGM).GenerateCode(GD, Fn, **ImplFnInfo);
3318 CGM.SetLLVMFunctionAttributesForDefinition(D, Fn);
static Address ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, CharUnits nonVirtualOffset, llvm::Value *virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase)
static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, const CXXConstructorDecl *Ctor, CXXCtorType Type, CallArgList &Args)
static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor)
CanSkipVTablePointerInitialization - Check whether we need to initialize any vtable pointers before c...
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 bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init)
static bool FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field)
static void EmitConditionalArrayDtorCall(const CXXDestructorDecl *DD, CodeGenFunction &CGF, llvm::Value *ShouldDeleteCondition)
static bool isMemcpyEquivalentSpecialMember(CodeGenModule &CGM, const CXXMethodDecl *D)
static bool HasTrivialDestructorBody(ASTContext &Context, const CXXRecordDecl *BaseClassDecl, const CXXRecordDecl *MostDerivedClassDecl)
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 isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit)
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
bool isPFPField(const FieldDecl *Field) 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.
bool hasPFPFields(QualType Ty) const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
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 * getOperatorGlobalDelete() const
const FunctionDecl * getGlobalArrayOperatorDelete() const
const FunctionDecl * getOperatorDelete() const
Expr * getOperatorDeleteThisArg() const
const FunctionDecl * getArrayOperatorDelete() 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.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
QualType getFunctionObjectParameterType() const
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
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
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
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()
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())
llvm::MDNode * getInlinedAt() const
void setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
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.
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_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.
@ ForceLeftToRight
! Language semantics require left-to-right evaluation.
@ Default
! No language constraints on evaluation order.
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 * 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...
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...
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)
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void 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.
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...
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
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,...
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.
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
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.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
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)
This class organizes the cross-function state that is used while generating LLVM code.
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).
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...
ItaniumVTableContext & getItaniumVTableContext()
ASTContext & getContext() const
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.
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
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 hasTrivialBody() const
Returns whether the function has a trivial body that does not require any specific codegen.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
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, void *&InsertPos)
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
bool isRelativeLayout() 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.
@ 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 ...
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
bool isa(CodeGen::Address addr)
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
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.