27 #include "llvm/IR/Intrinsics.h" 28 #include "llvm/IR/Metadata.h" 29 #include "llvm/Transforms/Utils/SanitizerStats.h" 31 using namespace clang;
32 using namespace CodeGen;
49 return layout.getNonVirtualAlignment();
63 CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
76 return std::min(actualBaseAlign, expectedTargetAlign);
79 CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
99 if (actualBaseAlign >= expectedBaseAlign) {
100 return expectedTargetAlign;
106 return std::min(actualBaseAlign, expectedTargetAlign);
110 assert(CurFuncDecl &&
"loading 'this' without a func declaration?");
111 assert(isa<CXXMethodDecl>(CurFuncDecl));
114 if (CXXThisAlignment.isZero()) {
118 auto RD = cast<CXXMethodDecl>(CurFuncDecl)->getParent();
119 CXXThisAlignment = CGM.getClassPointerAlignment(RD);
122 return Address(LoadCXXThis(), CXXThisAlignment);
136 CGM.getCXXABI().EmitMemberDataPointerAddress(*
this, E, base,
137 memberPtr, memberPtrType);
140 CharUnits memberAlign = getNaturalTypeAlignment(memberType, BaseInfo,
146 return Address(ptr, memberAlign);
159 assert(!Base->
isVirtual() &&
"Should not see virtual bases here!");
168 Offset += Layout.getBaseClassOffset(BaseDecl);
180 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
190 return llvm::ConstantInt::get(PtrDiffTy, Offset.
getQuantity());
202 bool BaseIsVirtual) {
217 if (!Offset.isZero()) {
218 V = Builder.CreateElementBitCast(V,
Int8Ty);
219 V = Builder.CreateConstInBoundsByteGEP(V, Offset);
221 V = Builder.CreateElementBitCast(V, ConvertType(Base));
233 assert(!nonVirtualOffset.
isZero() || virtualOffset !=
nullptr);
237 if (!nonVirtualOffset.
isZero()) {
238 baseOffset = llvm::ConstantInt::get(CGF.
PtrDiffTy,
241 baseOffset = CGF.
Builder.CreateAdd(virtualOffset, baseOffset);
244 baseOffset = virtualOffset;
250 ptr = CGF.
Builder.CreateInBoundsGEP(ptr, baseOffset,
"add.ptr");
256 assert(nearestVBase &&
"virtual offset without vbase?");
258 derivedClass, nearestVBase);
264 return Address(ptr, alignment);
272 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
281 if ((*Start)->isVirtual()) {
283 cast<CXXRecordDecl>((*Start)->getType()->getAs<
RecordType>()->getDecl());
290 CharUnits NonVirtualOffset = CGM.computeNonVirtualBaseClassOffset(
291 VBase ? VBase : Derived, Start, PathEnd);
296 if (VBase && Derived->
hasAttr<FinalAttr>()) {
299 NonVirtualOffset += vBaseOffset;
305 ConvertType((PathEnd[-1])->getType())->getPointerTo();
308 CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived);
312 if (NonVirtualOffset.
isZero() && !VBase) {
313 if (sanitizePerformTypeCheck()) {
315 SkippedChecks.
set(SanitizerKind::Null, !NullCheckValue);
316 EmitTypeCheck(TCK_Upcast, Loc, Value.
getPointer(),
317 DerivedTy, DerivedAlign, SkippedChecks);
319 return Builder.CreateBitCast(Value, BasePtrTy);
322 llvm::BasicBlock *origBB =
nullptr;
323 llvm::BasicBlock *endBB =
nullptr;
327 if (NullCheckValue) {
328 origBB = Builder.GetInsertBlock();
329 llvm::BasicBlock *notNullBB = createBasicBlock(
"cast.notnull");
330 endBB = createBasicBlock(
"cast.end");
333 Builder.CreateCondBr(isNull, endBB, notNullBB);
334 EmitBlock(notNullBB);
337 if (sanitizePerformTypeCheck()) {
339 SkippedChecks.
set(SanitizerKind::Null,
true);
340 EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc,
341 Value.
getPointer(), DerivedTy, DerivedAlign, SkippedChecks);
348 CGM.getCXXABI().GetVirtualBaseClassOffset(*
this, Value, Derived, VBase);
353 VirtualOffset, Derived, VBase);
356 Value = Builder.CreateBitCast(Value, BasePtrTy);
359 if (NullCheckValue) {
360 llvm::BasicBlock *notNullBB = Builder.GetInsertBlock();
361 Builder.CreateBr(endBB);
364 llvm::PHINode *PHI = Builder.CreatePHI(BasePtrTy, 2,
"cast.result");
365 PHI->addIncoming(Value.
getPointer(), notNullBB);
366 PHI->addIncoming(llvm::Constant::getNullValue(BasePtrTy), origBB);
378 bool NullCheckValue) {
379 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
383 llvm::Type *DerivedPtrTy = ConvertType(DerivedTy)->getPointerTo();
386 CGM.GetNonVirtualBaseClassOffset(Derived, PathBegin, PathEnd);
388 if (!NonVirtualOffset) {
390 return Builder.CreateBitCast(BaseAddr, DerivedPtrTy);
393 llvm::BasicBlock *CastNull =
nullptr;
394 llvm::BasicBlock *CastNotNull =
nullptr;
395 llvm::BasicBlock *CastEnd =
nullptr;
397 if (NullCheckValue) {
398 CastNull = createBasicBlock(
"cast.null");
399 CastNotNull = createBasicBlock(
"cast.notnull");
400 CastEnd = createBasicBlock(
"cast.end");
403 Builder.CreateCondBr(IsNull, CastNull, CastNotNull);
404 EmitBlock(CastNotNull);
409 Value = Builder.CreateGEP(Value, Builder.CreateNeg(NonVirtualOffset),
413 Value = Builder.CreateBitCast(Value, DerivedPtrTy);
416 if (NullCheckValue) {
417 Builder.CreateBr(CastEnd);
419 Builder.CreateBr(CastEnd);
422 llvm::PHINode *PHI = Builder.CreatePHI(Value->getType(), 2);
423 PHI->addIncoming(Value, CastNotNull);
424 PHI->addIncoming(llvm::Constant::getNullValue(Value->getType()), CastNull);
428 return Address(Value, CGM.getClassPointerAlignment(Derived));
434 if (!CGM.getCXXABI().NeedsVTTParameter(GD)) {
439 const CXXRecordDecl *RD = cast<CXXMethodDecl>(CurCodeDecl)->getParent();
444 uint64_t SubVTTIndex;
449 }
else if (RD == Base) {
452 assert(!CGM.getCXXABI().NeedsVTTParameter(CurGD) &&
453 "doing no-op VTT offset in base dtor/ctor?");
454 assert(!ForVirtualBase &&
"Can't have same class as virtual base!");
463 CGM.getVTables().getSubVTTIndex(RD,
BaseSubobject(Base, BaseOffset));
464 assert(SubVTTIndex != 0 &&
"Sub-VTT index must be greater than zero!");
467 if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
470 VTT = Builder.CreateConstInBoundsGEP1_64(VTT, SubVTTIndex);
473 VTT = CGM.getVTables().GetAddrOfVTT(RD);
474 VTT = Builder.CreateConstInBoundsGEP2_64(VTT, 0, SubVTTIndex);
486 : BaseClass(Base), BaseIsVirtual(BaseIsVirtual) {}
495 DerivedClass, BaseClass,
509 DynamicThisUseChecker(
const ASTContext &C) : super(C), UsesThis(
false) {}
516 void VisitCXXThisExpr(
const CXXThisExpr *E) { UsesThis =
true; }
521 DynamicThisUseChecker Checker(C);
523 return Checker.UsesThis;
531 "Must have base initializer!");
542 if (CtorType ==
Ctor_Base && isBaseVirtual)
573 if (!(CD && CD->isCopyOrMoveConstructor()) &&
595 for (
const auto *I : IndirectField->
chain())
609 "Must have member initializer!");
610 assert(MemberInit->
getInit() &&
"Must have initializer!");
614 QualType FieldType = Field->getType();
635 unsigned SrcArgIndex =
660 switch (getEvaluationKind(FieldType)) {
663 EmitExprAsInit(Init, Field, LHS,
false);
666 EmitStoreThroughLValue(RHS, LHS);
670 EmitComplexExprIntoLValue(Init, LHS,
true);
678 EmitAggExpr(Init, Slot);
686 if (needsEHCleanup(dtorKind))
687 pushEHDestroy(dtorKind, LHS.
getAddress(), FieldType);
745 Prologue ? cast<CXXConstructorDecl>(CurGD.getDecl())->getParent()
746 : cast<CXXDestructorDecl>(CurGD.getDecl())->getParent();
749 struct SizeAndOffset {
754 unsigned PtrSize = CGM.getDataLayout().getPointerSizeInBits();
763 size_t NumFields = 0;
764 for (
const auto *Field : ClassDecl->
fields()) {
766 std::pair<CharUnits, CharUnits> FieldInfo =
769 assert(NumFields < SSV.size());
773 assert(NumFields == SSV.size());
774 if (SSV.size() <= 1)
return;
779 llvm::FunctionType *FTy =
780 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
781 llvm::Constant *F = CGM.CreateRuntimeFunction(
782 FTy, Prologue ?
"__asan_poison_intra_object_redzone" 783 :
"__asan_unpoison_intra_object_redzone");
786 ThisPtr = Builder.CreatePtrToInt(ThisPtr, IntPtrTy);
790 for (
size_t i = 0; i < SSV.size(); i++) {
791 uint64_t AsanAlignment = 8;
792 uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
793 uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
794 uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
795 if (PoisonSize < AsanAlignment || !SSV[i].Size ||
796 (NextField % AsanAlignment) != 0)
799 F, {Builder.CreateAdd(ThisPtr, Builder.getIntN(PtrSize, EndOffset)),
800 Builder.getIntN(PtrSize, PoisonSize)});
806 EmitAsanPrologueOrEpilogue(
true);
810 assert((CGM.getTarget().getCXXABI().hasConstructorVariants() ||
812 "can only generate complete ctor for this ABI");
816 if (CtorType ==
Ctor_Complete && IsConstructorDelegationValid(Ctor) &&
817 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
824 assert(Definition == Ctor &&
"emitting wrong constructor body");
828 bool IsTryBody = (Body && isa<CXXTryStmt>(Body));
830 EnterCXXTryStmt(*cast<CXXTryStmt>(Body),
true);
832 incrementProfileCounter(Body);
841 EmitCtorPrologue(Ctor, CtorType, Args);
845 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
856 ExitCXXTryStmt(*cast<CXXTryStmt>(Body),
true);
864 class CopyingValueRepresentation {
867 : CGF(CGF), OldSanOpts(CGF.
SanOpts) {
871 ~CopyingValueRepresentation() {
881 class FieldMemcpyizer {
885 : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
887 FirstField(
nullptr), LastField(
nullptr), FirstFieldOffset(0),
888 LastFieldOffset(0), LastAddedFieldIndex(0) {}
890 bool isMemcpyableField(
FieldDecl *F)
const {
907 CharUnits getMemcpySize(uint64_t FirstByteOffset)
const {
908 unsigned LastFieldSize =
909 LastField->isBitField() ?
910 LastField->getBitWidthValue(CGF.
getContext()) :
912 uint64_t MemcpySizeBits =
913 LastFieldOffset + LastFieldSize - FirstByteOffset +
927 uint64_t FirstByteOffset;
928 if (FirstField->isBitField()) {
936 FirstByteOffset = FirstFieldOffset;
939 CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
955 FirstField =
nullptr;
964 llvm::PointerType *DPT = DestPtr.
getType();
966 llvm::Type::getInt8PtrTy(CGF.
getLLVMContext(), DPT->getAddressSpace());
969 llvm::PointerType *SPT = SrcPtr.
getType();
971 llvm::Type::getInt8PtrTy(CGF.
getLLVMContext(), SPT->getAddressSpace());
980 FirstFieldOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
981 LastFieldOffset = FirstFieldOffset;
991 "Cannot aggregate fields out of order.");
997 uint64_t FOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
998 if (FOffset < FirstFieldOffset) {
1000 FirstFieldOffset = FOffset;
1001 }
else if (FOffset > LastFieldOffset) {
1003 LastFieldOffset = FOffset;
1011 uint64_t FirstFieldOffset, LastFieldOffset;
1012 unsigned LastAddedFieldIndex;
1015 class ConstructorMemcpyizer :
public FieldMemcpyizer {
1030 if (!MemcpyableCtor)
1033 assert(Field &&
"No field for member init.");
1044 if (!isMemcpyableField(Field))
1054 : FieldMemcpyizer(CGF, CD->
getParent(), getTrivialCopySource(CGF, CD, Args)),
1055 ConstructorDecl(CD),
1062 if (isMemberInitMemcpyable(MemberInit)) {
1063 AggregatedInits.push_back(MemberInit);
1064 addMemcpyableField(MemberInit->
getMember());
1066 emitAggregatedInits();
1068 ConstructorDecl, Args);
1072 void emitAggregatedInits() {
1073 if (AggregatedInits.size() <= 1) {
1076 if (!AggregatedInits.empty()) {
1077 CopyingValueRepresentation CVR(CGF);
1079 AggregatedInits[0], ConstructorDecl, Args);
1080 AggregatedInits.clear();
1086 pushEHDestructors();
1088 AggregatedInits.clear();
1091 void pushEHDestructors() {
1096 for (
unsigned i = 0; i < AggregatedInits.size(); ++i) {
1109 emitAggregatedInits();
1114 bool MemcpyableCtor;
1119 class AssignmentMemcpyizer :
public FieldMemcpyizer {
1124 if (!AssignmentsMemcpyable)
1128 if (BO->getOpcode() != BO_Assign)
1134 if (!Field || !isMemcpyableField(Field))
1136 Stmt *RHS = BO->getRHS();
1138 RHS = EC->getSubExpr();
1141 if (
MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
1142 if (ME2->getMemberDecl() == Field)
1154 if (!Field || !isMemcpyableField(Field))
1157 if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->
getMemberDecl()))
1160 }
else if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
1162 if (!FD || FD->
getBuiltinID() != Builtin::BI__builtin_memcpy)
1164 Expr *DstPtr = CE->getArg(0);
1166 DstPtr = DC->getSubExpr();
1168 if (!DUO || DUO->
getOpcode() != UO_AddrOf)
1174 if (!Field || !isMemcpyableField(Field))
1176 Expr *SrcPtr = CE->getArg(1);
1178 SrcPtr = SC->getSubExpr();
1180 if (!SUO || SUO->
getOpcode() != UO_AddrOf)
1183 if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->
getMemberDecl()))
1191 bool AssignmentsMemcpyable;
1197 : FieldMemcpyizer(CGF, AD->
getParent(), Args[Args.size() - 1]),
1199 assert(Args.size() == 2);
1202 void emitAssignment(
Stmt *S) {
1205 addMemcpyableField(F);
1206 AggregatedStmts.push_back(S);
1208 emitAggregatedStmts();
1213 void emitAggregatedStmts() {
1214 if (AggregatedStmts.size() <= 1) {
1215 if (!AggregatedStmts.empty()) {
1216 CopyingValueRepresentation CVR(CGF);
1223 AggregatedStmts.clear();
1227 emitAggregatedStmts();
1234 const auto *BaseClassDecl =
1236 return BaseClassDecl->isDynamicClass();
1245 return EmitDelegatingCXXConstructorCall(CD, Args);
1252 llvm::BasicBlock *BaseCtorContinueBB =
nullptr;
1254 !CGM.getTarget().getCXXABI().hasConstructorVariants()) {
1257 BaseCtorContinueBB =
1258 CGM.getCXXABI().EmitCtorCompleteObjectHandler(*
this, ClassDecl);
1259 assert(BaseCtorContinueBB);
1264 for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
1265 if (CGM.getCodeGenOpts().StrictVTablePointers &&
1266 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1268 CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
1272 if (BaseCtorContinueBB) {
1274 Builder.CreateBr(BaseCtorContinueBB);
1275 EmitBlock(BaseCtorContinueBB);
1279 for (; B != E && (*B)->isBaseInitializer(); B++) {
1280 assert(!(*B)->isBaseVirtual());
1282 if (CGM.getCodeGenOpts().StrictVTablePointers &&
1283 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1285 CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
1289 CXXThisValue = OldThis;
1291 InitializeVTablePointers(ClassDecl);
1295 ConstructorMemcpyizer CM(*
this, CD, Args);
1296 for (; B != E; B++) {
1300 "Delegating initializer on non-delegating constructor");
1301 CM.addMemberInitializer(Member);
1322 for (
const auto *Field : BaseClassDecl->
fields())
1327 for (
const auto &I : BaseClassDecl->
bases()) {
1332 cast<CXXRecordDecl>(I.getType()->castAs<
RecordType>()->getDecl());
1334 MostDerivedClassDecl))
1338 if (BaseClassDecl == MostDerivedClassDecl) {
1340 for (
const auto &I : BaseClassDecl->
vbases()) {
1342 cast<CXXRecordDecl>(I.getType()->castAs<
RecordType>()->getDecl());
1344 MostDerivedClassDecl))
1383 for (
const auto *Field : ClassDecl->
fields())
1401 llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
1402 TrapCall->setDoesNotReturn();
1403 TrapCall->setDoesNotThrow();
1404 Builder.CreateUnreachable();
1405 Builder.ClearInsertionPoint();
1411 incrementProfileCounter(Body);
1420 if (HaveInsertPoint())
1422 false, LoadCXXThisAddress());
1428 bool isTryBody = (Body && isa<CXXTryStmt>(Body));
1430 EnterCXXTryStmt(*cast<CXXTryStmt>(Body),
true);
1431 EmitAsanPrologueOrEpilogue(
false);
1442 case Dtor_Comdat: llvm_unreachable(
"not expecting a COMDAT");
1443 case Dtor_Deleting: llvm_unreachable(
"already handled deleting case");
1447 "can't emit a dtor without a body for non-Microsoft ABIs");
1453 EmitCXXDestructorCall(Dtor,
Dtor_Base,
false,
1454 false, LoadCXXThisAddress());
1471 if (CGM.getCodeGenOpts().StrictVTablePointers &&
1472 CGM.getCodeGenOpts().OptimizationLevel > 0)
1473 CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis());
1474 InitializeVTablePointers(Dtor->
getParent());
1478 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
1482 assert(Dtor->
isImplicit() &&
"bodyless dtor not implicit");
1488 CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
1498 ExitCXXTryStmt(*cast<CXXTryStmt>(Body),
true);
1502 const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl());
1504 assert(isa<CompoundStmt>(RootS) &&
1505 "Body of an implicit assignment operator should be compound stmt.");
1506 const CompoundStmt *RootCS = cast<CompoundStmt>(RootS);
1510 incrementProfileCounter(RootCS);
1511 AssignmentMemcpyizer AM(*
this, AssignOp, Args);
1512 for (
auto *I : RootCS->
body())
1513 AM.emitAssignment(I);
1533 LoadThisForDtorDelete(CGF, Dtor),
1540 bool ReturnAfterDelete) {
1544 = CGF.
Builder.CreateIsNull(ShouldDeleteCondition);
1545 CGF.
Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
1551 LoadThisForDtorDelete(CGF, Dtor),
1554 ReturnAfterDelete &&
1555 "unexpected value for ReturnAfterDelete");
1556 if (ReturnAfterDelete)
1559 CGF.
Builder.CreateBr(continueBB);
1568 CallDtorDeleteConditional(
llvm::Value *ShouldDeleteCondition)
1569 : ShouldDeleteCondition(ShouldDeleteCondition) {
1570 assert(ShouldDeleteCondition !=
nullptr);
1574 EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition,
1582 bool useEHCleanupForArray;
1586 bool useEHCleanupForArray)
1587 : field(field), destroyer(destroyer),
1588 useEHCleanupForArray(useEHCleanupForArray) {}
1599 flags.isForNormalCleanup() && useEHCleanupForArray);
1609 llvm::ConstantInt::get(CGF.
SizeTy, PoisonSize)};
1613 llvm::FunctionType *FnType =
1614 llvm::FunctionType::get(CGF.
VoidTy, ArgTypes,
false);
1638 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1643 unsigned fieldIndex = 0;
1644 int startIndex = -1;
1651 startIndex = fieldIndex;
1658 }
else if (startIndex >= 0) {
1660 PoisonMembers(CGF, startIndex, fieldIndex);
1674 unsigned layoutEndOffset) {
1679 llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
1701 if (PoisonSize == 0)
1704 EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize);
1726 EmitSanitizerDtorCallback(CGF, VTablePtr, PoisonSize);
1740 "Should not emit dtor epilogue for non-exported trivial dtor!");
1746 "operator delete missing - EnterDtorCleanups");
1747 if (CXXStructorImplicitParamValue) {
1751 EmitConditionalDtorDeleteCall(*
this, CXXStructorImplicitParamValue,
1754 EHStack.pushCleanup<CallDtorDeleteConditional>(
1760 LoadThisForDtorDelete(*
this, DD),
1762 EmitBranchThroughCleanup(ReturnBlock);
1780 if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1781 SanOpts.has(SanitizerKind::Memory) && ClassDecl->
getNumVBases() &&
1787 for (
const auto &
Base : ClassDecl->
vbases()) {
1789 = cast<CXXRecordDecl>(
Base.getType()->getAs<
RecordType>()->getDecl());
1806 if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1807 SanOpts.has(SanitizerKind::Memory) && !ClassDecl->
getNumVBases() &&
1812 for (
const auto &
Base : ClassDecl->
bases()) {
1814 if (
Base.isVirtual())
1830 if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1831 SanOpts.has(SanitizerKind::Memory))
1835 for (
const auto *Field : ClassDecl->
fields()) {
1838 if (!dtorKind)
continue;
1844 CleanupKind cleanupKind = getCleanupKind(dtorKind);
1845 EHStack.pushCleanup<DestroyField>(cleanupKind, Field,
1846 getDestroyer(dtorKind),
1864 emitArrayLength(arrayType, elementType, arrayBegin);
1866 EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E, zeroInitialize);
1882 bool zeroInitialize) {
1888 llvm::BranchInst *zeroCheckBranch =
nullptr;
1891 llvm::ConstantInt *constantCount
1892 = dyn_cast<llvm::ConstantInt>(numElements);
1893 if (constantCount) {
1895 if (constantCount->isZero())
return;
1899 llvm::BasicBlock *loopBB = createBasicBlock(
"new.ctorloop");
1900 llvm::Value *iszero = Builder.CreateIsNull(numElements,
"isempty");
1901 zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB);
1907 llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements,
1911 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
1912 llvm::BasicBlock *loopBB = createBasicBlock(
"arrayctor.loop");
1914 llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2,
1916 cur->addIncoming(arrayBegin, entryBB);
1934 EmitNullInitialization(curAddr, type);
1951 Destroyer *destroyer = destroyCXXObject;
1952 pushRegularPartialArrayCleanup(arrayBegin, cur, type, eltAlignment,
1962 Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(
SizeTy, 1),
1964 cur->addIncoming(next, Builder.GetInsertBlock());
1967 llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd,
"arrayctor.done");
1968 llvm::BasicBlock *contBB = createBasicBlock(
"arrayctor.cont");
1969 Builder.CreateCondBr(done, contBB, loopBB);
1972 if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB);
1983 assert(!dtor->isTrivial());
1990 bool ForVirtualBase,
1991 bool Delegating,
Address This,
2002 assert(E->
getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
2006 Address Src = EmitLValue(Arg).getAddress();
2008 EmitAggregateCopyCtor(This, Src, DestTy, SrcTy);
2015 ? EvaluationOrder::ForceLeftToRight
2020 EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args);
2033 if (
P->getType().isDestructedType())
2049 bool ForVirtualBase,
2063 assert(Args.size() == 1 &&
"trivial default ctor with args");
2071 assert(Args.size() == 2 &&
"unexpected argcount for trivial ctor");
2074 Address Src(Args[1].RV.getScalarVal(), getNaturalTypeAlignment(SrcTy));
2076 EmitAggregateCopyCtor(This, Src, DestTy, SrcTy);
2080 bool PassPrototypeArgs =
true;
2085 EmitInlinedInheritingCXXConstructorCall(D, Type, ForVirtualBase,
2093 CGM.getCXXABI().addImplicitConstructorArgs(*
this, D, Type, ForVirtualBase,
2097 llvm::Constant *CalleePtr =
2099 const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(
2100 Args, D, Type, ExtraArgs.
Prefix, ExtraArgs.
Suffix, PassPrototypeArgs);
2115 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2117 CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) &&
2118 CGM.getCodeGenOpts().StrictVTablePointers)
2119 EmitVTableAssumptionLoads(ClassDecl, This);
2130 if (InheritedFromVBase &&
2131 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
2136 Args.push_back(ThisArg);
2137 }
else if (!CXXInheritedCtorInitExprArgs.empty()) {
2139 assert(CXXInheritedCtorInitExprArgs.size() >= D->
getNumParams() &&
2140 "wrong number of parameters for inherited constructor call");
2141 Args = CXXInheritedCtorInitExprArgs;
2145 Args.push_back(ThisArg);
2146 const auto *OuterCtor = cast<CXXConstructorDecl>(CurCodeDecl);
2147 assert(OuterCtor->getNumParams() == D->
getNumParams());
2148 assert(!OuterCtor->isVariadic() &&
"should have been inlined");
2150 for (
const auto *Param : OuterCtor->parameters()) {
2152 OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
2154 EmitDelegateCallArg(Args, Param, E->
getLocation());
2157 if (Param->hasAttr<PassObjectSizeAttr>()) {
2158 auto *POSParam = SizeArguments[Param];
2159 assert(POSParam &&
"missing pass_object_size value for forwarding");
2160 EmitDelegateCallArg(Args, POSParam, E->
getLocation());
2165 EmitCXXConstructorCall(D,
Ctor_Base, ForVirtualBase,
false,
2177 CXXInheritedCtorInitExprArgs = Args;
2180 QualType RetType = BuildFunctionArgList(CurGD, Params);
2184 CGM.getCXXABI().addImplicitConstructorArgs(*
this, Ctor, CtorType,
2185 ForVirtualBase, Delegating, Args);
2188 assert(Args.size() >= Params.size() &&
"too few arguments for call");
2189 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
2190 if (I < Params.size() && isa<ImplicitParamDecl>(Params[I])) {
2191 const RValue &RV = Args[I].RV;
2192 assert(!RV.
isComplex() &&
"complex indirect params not supported");
2196 EmitParmDecl(*Params[I], Val, I + 1);
2204 ReturnValue = CreateIRTemp(RetType,
"retval.inhctor");
2206 CGM.getCXXABI().EmitInstanceFunctionProlog(*
this);
2207 CXXThisValue = CXXABIThisValue;
2210 EmitCtorPrologue(Ctor, CtorType, Params);
2222 if (!NonVirtualOffset.
isZero())
2230 Builder.CreateICmpEQ(VPtrValue, VTableGlobal,
"cmp.vtables");
2231 Builder.CreateAssumption(Cmp);
2236 if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))
2237 for (
const VPtr &Vptr : getVTablePointers(ClassDecl))
2238 EmitVTableAssumptionLoad(Vptr, This);
2254 llvm::Type *t = CGM.getTypes().ConvertType(QT);
2255 Src = Builder.CreateBitCast(Src, t);
2262 EmitCXXConstructorCall(D,
Ctor_Complete,
false,
false, This, Args);
2272 FunctionArgList::const_iterator I = Args.begin(), E = Args.end();
2273 assert(I != E &&
"no parameters to constructor");
2276 Address This = LoadCXXThisAddress();
2282 if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
2283 assert(I != E &&
"cannot skip vtt parameter, already done with args");
2284 assert((*I)->getType()->isPointerType() &&
2285 "skipping parameter not of vtt type");
2290 for (; I != E; ++I) {
2293 EmitDelegateCallArg(DelegateArgs, param, Loc);
2296 EmitCXXConstructorCall(Ctor, CtorType,
false,
2297 true, This, DelegateArgs);
2308 : Dtor(D), Addr(Addr),
Type(Type) {}
2322 Address ThisPtr = LoadCXXThisAddress();
2333 if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) {
2337 EHStack.pushCleanup<CallDelegatingCtorDtor>(
EHCleanup,
2338 ClassDecl->getDestructor(),
2345 bool ForVirtualBase,
2348 CGM.getCXXABI().EmitDestructorCall(*
this, DD, Type, ForVirtualBase,
2358 : Dtor(D), Addr(Addr) {}
2375 if (!ClassDecl)
return;
2379 assert(D && D->
isUsed() &&
"destructor not marked as used!");
2380 PushDestructorCleanup(D, Addr);
2386 CGM.getCXXABI().getVTableAddressPointInStructor(
2389 if (!VTableAddressPoint)
2396 if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*
this, Vptr)) {
2400 VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(
2409 Address VTableField = LoadCXXThisAddress();
2411 if (!NonVirtualOffset.
isZero() || VirtualOffset)
2413 *
this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.
VTableClass,
2419 llvm::FunctionType::get(CGM.Int32Ty,
true)
2422 VTableField = Builder.CreateBitCast(VTableField, VTablePtrTy->getPointerTo());
2423 VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy);
2425 llvm::StoreInst *
Store = Builder.CreateStore(VTableAddressPoint, VTableField);
2426 TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTablePtrTy);
2427 CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
2428 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2429 CGM.getCodeGenOpts().StrictVTablePointers)
2430 CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.
VTableClass);
2440 false, VTableClass, VBases,
2448 bool BaseIsNonVirtualPrimaryBase,
2454 if (!BaseIsNonVirtualPrimaryBase) {
2456 VPtr Vptr = {
Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
2457 Vptrs.push_back(Vptr);
2463 for (
const auto &I : RD->
bases()) {
2465 = cast<CXXRecordDecl>(I.getType()->getAs<
RecordType>()->getDecl());
2473 bool BaseDeclIsNonVirtualPrimaryBase;
2475 if (I.isVirtual()) {
2477 if (!VBases.insert(BaseDecl).second)
2485 BaseDeclIsNonVirtualPrimaryBase =
false;
2490 BaseOffsetFromNearestVBase =
2492 BaseDeclIsNonVirtualPrimaryBase = Layout.
getPrimaryBase() == BaseDecl;
2497 I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
2498 BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
2508 if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD))
2509 for (
const VPtr &Vptr : getVTablePointers(RD))
2510 InitializeVTablePointer(Vptr);
2513 CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*
this, RD);
2519 Address VTablePtrSrc = Builder.CreateElementBitCast(This, VTableTy);
2520 llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc,
"vtable");
2521 TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy);
2522 CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo);
2524 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2525 CGM.getCodeGenOpts().StrictVTablePointers)
2526 CGM.DecorateInstructionWithInvariantGroup(VTable, RD);
2552 if (MD->isVirtual()) {
2556 if (isa<CXXDestructorDecl>(MD) && MD->isImplicit())
2569 if (SanOpts.has(SanitizerKind::CFIVCall))
2571 else if (CGM.getCodeGenOpts().WholeProgramVTables &&
2572 CGM.HasHiddenLTOVisibility(RD)) {
2573 llvm::Metadata *MD =
2576 llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
2580 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
2581 {CastedVTable, TypeId});
2582 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
2590 if (!SanOpts.has(SanitizerKind::CFICastStrict))
2593 EmitVTablePtrCheck(RD, VTable, TCK, Loc);
2608 const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassTy->getDecl());
2613 if (!SanOpts.has(SanitizerKind::CFICastStrict))
2616 llvm::BasicBlock *ContBlock =
nullptr;
2620 Builder.CreateIsNotNull(Derived,
"cast.nonnull");
2622 llvm::BasicBlock *CheckBlock = createBasicBlock(
"cast.check");
2623 ContBlock = createBasicBlock(
"cast.cont");
2625 Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
2627 EmitBlock(CheckBlock);
2631 std::tie(VTable, ClassDecl) = CGM.getCXXABI().LoadVTablePtr(
2634 EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
2637 Builder.CreateBr(ContBlock);
2638 EmitBlock(ContBlock);
2646 if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
2647 !CGM.HasHiddenLTOVisibility(RD))
2651 llvm::SanitizerStatKind SSK;
2654 M = SanitizerKind::CFIVCall;
2655 SSK = llvm::SanStat_CFI_VCall;
2658 M = SanitizerKind::CFINVCall;
2659 SSK = llvm::SanStat_CFI_NVCall;
2661 case CFITCK_DerivedCast:
2662 M = SanitizerKind::CFIDerivedCast;
2663 SSK = llvm::SanStat_CFI_DerivedCast;
2665 case CFITCK_UnrelatedCast:
2666 M = SanitizerKind::CFIUnrelatedCast;
2667 SSK = llvm::SanStat_CFI_UnrelatedCast;
2670 llvm_unreachable(
"not expecting CFITCK_ICall");
2674 if (
getContext().getSanitizerBlacklist().isBlacklistedType(M, TypeName))
2678 EmitSanitizerStatReport(SSK);
2680 llvm::Metadata *MD =
2686 CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, TypeId});
2688 llvm::Constant *StaticData[] = {
2689 llvm::ConstantInt::get(
Int8Ty, TCK),
2690 EmitCheckSourceLocation(Loc),
2694 auto CrossDsoTypeId = CGM.CreateCrossDsoCfiTypeId(MD);
2695 if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
2696 EmitCfiSlowPathCheck(M, TypeTest, CrossDsoTypeId, CastedVTable, StaticData);
2700 if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
2701 EmitTrapCheck(TypeTest);
2705 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
2706 CGM.getLLVMContext(),
2707 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
2709 CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, AllVtables});
2710 EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
2711 StaticData, {CastedVTable, ValidVtable});
2715 if (!CGM.getCodeGenOpts().WholeProgramVTables ||
2716 !SanOpts.has(SanitizerKind::CFIVCall) ||
2717 !CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall) ||
2718 !CGM.HasHiddenLTOVisibility(RD))
2723 SanitizerKind::CFIVCall, TypeName);
2730 EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
2732 llvm::Metadata *MD =
2734 llvm::Value *TypeId = llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
2738 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
2739 {CastedVTable, llvm::ConstantInt::get(
Int32Ty, VTableByteOffset),
2741 llvm::Value *CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
2743 EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall),
2744 SanitizerHandler::CFICheckFail,
nullptr,
nullptr);
2746 return Builder.CreateBitCast(
2747 Builder.CreateExtractValue(CheckedLoad, 0),
2748 cast<llvm::PointerType>(VTable->getType())->getElementType());
2756 CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
2757 llvm::Constant *calleePtr =
2758 CGM.GetAddrOfFunction(
GlobalDecl(callOperator),
2759 CGM.getTypes().GetFunctionType(calleeFnInfo));
2766 if (!resultType->isVoidType() &&
2769 returnSlot =
ReturnValueSlot(ReturnValue, resultType.isVolatileQualified());
2777 RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs);
2780 if (!resultType->isVoidType() && returnSlot.
isNull()) {
2781 if (
getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
2784 EmitReturnOfRValue(RV, resultType);
2786 EmitBranchThroughCleanup(ReturnBlock);
2790 const BlockDecl *BD = BlockInfo->getBlockDecl();
2799 CGM.ErrorUnsupported(CurCodeDecl,
"lambda conversion to variadic function");
2807 Address ThisPtr = GetAddrOfBlockDecl(variable,
false);
2812 EmitDelegateCallArg(CallArgs, param, param->getLocStart());
2815 "generic lambda interconversion to block not implemented");
2816 EmitForwardingCallToLambda(CallOp, CallArgs);
2831 EmitDelegateCallArg(CallArgs, Param, Param->getLocStart());
2840 void *InsertPos =
nullptr;
2843 assert(CorrespondingCallOpSpecialization);
2844 CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
2846 EmitForwardingCallToLambda(CallOp, CallArgs);
2853 CGM.ErrorUnsupported(MD,
"lambda conversion to variadic function");
2857 EmitLambdaDelegatingInvokeBody(MD);
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
ReturnValueSlot - Contains the address where the return value of a function can be stored...
void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type)
EnterDtorCleanups - Enter the cleanups necessary to complete the given phase of destruction for a des...
An instance of this class is created to represent a function declaration or definition.
Expr * getInit() const
Get the initializer.
void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, const FunctionArgList &Args, SourceLocation Loc)
A (possibly-)qualified type.
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Emit the address of a field using a member data pointer.
void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args)
EmitCtorPrologue - This routine generates necessary code to initialize base classes and non-static da...
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
CodeGenTypes & getTypes()
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
bool isBlacklistedType(SanitizerMask Mask, StringRef MangledTypeName, StringRef Category=StringRef()) const
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
capture_const_iterator capture_begin() const
llvm::LLVMContext & getLLVMContext()
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
Stmt - This represents one statement.
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...
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
Checking the 'this' pointer for a constructor call.
const Type * getTypeForDecl() const
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
Defines the C++ template declaration subclasses.
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)
unsigned getFieldIndex() const
getFieldIndex - Returns the index of this field within its record, as appropriate for passing to ASTR...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
const RecordDecl * getParent() const
getParent - Returns the parent of this field declaration, which is the struct in which this field is ...
static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D)
The base class of the type hierarchy.
Expr * getOperatorDeleteThisArg() const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Represents a call to a C++ constructor.
bool isZero() const
isZero - Test whether the quantity equals zero.
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference...
SourceLocation getLocEnd() const LLVM_READONLY
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
Represents a C++ constructor within a class.
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
const RecordType * getAsUnionType() const
NOTE: getAs*ArrayType are methods on ASTContext.
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
bool isIndirectMemberInitializer() const
const CXXBaseSpecifier *const * path_const_iterator
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
const T * getAs() const
Member-template getAs<specific 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 * getPointer() const
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
The collection of all-type qualifiers we support.
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
static const CXXRecordDecl * LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD)
const TargetInfo & getTarget() const
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
Address getAddress() const
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool hasTrivialBody() const
Returns whether the function has a trivial body that does not require any specific codegen...
const CXXRecordDecl * NearestVBase
llvm::SmallPtrSet< const CXXRecordDecl *, 4 > VisitedVirtualBasesSetTy
void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, Address This, Address Src, const CXXConstructExpr *E)
field_range fields() const
bool isVolatileQualified() const
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::IntegerType * SizeTy
bool isReferenceType() const
void pushEHDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushEHDestroy - Push the standard destructor for the given type as an EH-only cleanup.
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...
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, Address This, const CXXConstructExpr *E)
void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD)
ArrayRef< ParmVarDecl * > parameters() const
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init)
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 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...
QualType getThisType(ASTContext &C) const
Returns the type of the this pointer.
bool isBitField() const
Determines whether this field is a bitfield.
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool isBaseVirtual() const
Returns whether the base is virtual or not.
CharUnits - This is an opaque type for sizes expressed in character units.
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...
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
ArrayRef< NamedDecl * > chain() const
unsigned char PointerWidthInBits
The width of a pointer into the generic address space.
CharUnits getAlignment() const
Return the alignment of this pointer.
llvm::PointerType * VoidPtrTy
A builtin binary operation expression such as "x + y" or "x <= y".
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind...
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.
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
const Type * getClass() const
Scope - A scope is a transient data structure that is used while parsing the program.
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
param_type_iterator param_type_begin() const
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
bool isAnyMemberInitializer() const
base_class_iterator bases_begin()
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
FieldDecl * getAnyMember() const
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
CharUnits getPointerAlign() const
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
bool isAbstract() const
Determine whether this class has a pure virtual function.
static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
init_iterator init_begin()
Retrieve an iterator to the first initializer.
bool isAnonymousStructOrUnion() const
isAnonymousStructOrUnion - Whether this is an anonymous struct or union.
Represents the this expression in C++.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field)
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
CanQualType getReturnType() const
static CharUnits One()
One - Construct a CharUnits quantity of one.
CompoundStmt - This represents a group of statements like { stmt stmt }.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ASTContext & getContext() const
Represents a prototype with parameter type info, e.g.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
bool isDynamicClass() const
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF, CXXCtorInitializer *MemberInit, LValue &LHS)
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
CXXDtorType
C++ destructor types.
BlockDecl - This represents a block literal declaration, which is like an unnamed FunctionDecl...
Expr - This represents one expression.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
bool isVariadic() const
Whether this function is variadic.
bool isDefaulted() const
Whether this function is defaulted per C++0x.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
const FunctionProtoType * T
void EmitVTableAssumptionLoad(const VPtr &vptr, Address This)
Emit assumption that vptr load == global vtable.
const T * castAs() const
Member-template castAs<specific type>.
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, bool ZeroInitialization=false)
EmitCXXAggrConstructorCall - Emit a loop to call a particular constructor for each of several members...
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
Represents a C++ destructor within a class.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl...
void EmitLambdaBlockInvokeBody()
llvm::PointerType * getType() const
Return the type of the pointer value.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
void add(RValue rvalue, QualType type, bool needscopy=false)
void EmitAsanPrologueOrEpilogue(bool Prologue)
char __ovld __cnfn min(char x, char y)
Returns y if y < x, otherwise it returns x.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
llvm::LLVMContext & getLLVMContext()
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
llvm::IntegerType * Int32Ty
void EmitConstructorBody(FunctionArgList &Args)
EmitConstructorBody - Emits the body of the current constructor.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
QualType getRecordType(const RecordDecl *Decl) const
A scoped helper to set the current debug location to an inlined location.
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, CallArgList &CallArgs)
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
const TargetInfo & getTarget() const
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
const LangOptions & getLangOpts() const
ASTContext & getContext() const
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
forAddr - Make a slot for an aggregate value.
The COMDAT used for dtors.
const SanitizerBlacklist & getSanitizerBlacklist() const
GlobalDecl - represents a global declaration.
static const RecordType * getRecordType(QualType QT)
Checks that the passed in QualType either is of RecordType or points to RecordType.
The l-value was considered opaque, so the alignment was determined from a type.
RecordDecl * getDecl() const
static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor)
CanSkipVTablePointerInitialization - Check whether we need to initialize any vtable pointers before c...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
Enumerates target-specific builtins in their own namespaces within namespace clang.
Address CreateBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Represents a call to an inherited base class constructor from an inheriting constructor.
void PushDestructorCleanup(QualType T, Address Addr)
PushDestructorCleanup - Push a cleanup to call the complete-object destructor of an object of the giv...
Encodes a location in the source.
QualType getReturnType() const
Expr * getSubExpr() const
void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This)
Emit assumption load for all bases.
bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
Represents a call to a member function that may be written either with member call syntax (e...
const Decl * getDecl() const
init_iterator init_end()
Retrieve an iterator past the last initializer.
A scoped helper to set the current debug location to the specified location or preferred location of ...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
Represents a static or instance method of a struct/union/class.
const ConstantArrayType * getAsConstantArrayType(QualType T) const
void EmitStmt(const Stmt *S, ArrayRef< const Attr *> Attrs=None)
EmitStmt - Emit the code for the statement.
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
const ParmVarDecl * getParamDecl(unsigned i) const
SanitizerSet SanOpts
Sanitizers enabled for this function.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
All available information about a concrete callee.
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
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...
static void EmitBaseInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *BaseInit, CXXCtorType CtorType)
CXXCtorType
C++ constructor types.
std::pair< CharUnits, CharUnits > getTypeInfoInChars(const Type *T) const
SourceLocation getLocation() const LLVM_READONLY
void InitializeVTablePointer(const VPtr &vptr)
Initialize the vtable pointer of the given subobject.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
CGFunctionInfo - Class to encapsulate the information about a function definition.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset...
Dataflow Directional Tag Classes.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This)
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
void EmitVTablePtrCheckForCast(QualType T, llvm::Value *Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, const CXXConstructorDecl *Ctor, CXXCtorType Type, CallArgList &Args)
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
IndirectFieldDecl - An instance of this class is created to represent a field injected from an anonym...
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::IntegerType * IntPtrTy
void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, const FunctionArgList &Args)
bool areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee? This is a fundamental language change...
const CXXRecordDecl * getParent() const
Returns the parent of this method declaration, which is the class in which this method is defined...
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
void InitializeVTablePointers(const CXXRecordDecl *ClassDecl)
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
A pointer to member type per C++ 8.3.3 - Pointers to members.
void EmitAggregateCopy(Address DestPtr, Address SrcPtr, QualType EltTy, bool isVolatile=false, bool isAssignment=false)
EmitAggregateCopy - Emit an aggregate copy.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool hasObjCLifetime() const
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type. ...
JumpDest ReturnBlock
ReturnBlock - Unified return block.
const FunctionDecl * getOperatorDelete() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
StructorType getFromCtorType(CXXCtorType T)
CharUnits OffsetFromNearestVBase
CodeGenTypes & getTypes() const
Represents a C++ base or member initializer.
Address getBitFieldAddress() const
IndirectFieldDecl * getIndirectMember() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
llvm::PointerType * Int8PtrTy
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.
Expr * getArg(unsigned Arg)
Return the specified argument.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
ABIArgInfo & getReturnInfo()
Represents a base class of a C++ class.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass)
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Address LoadCXXThisAddress()
A template argument list.
llvm::IntegerType * PtrDiffTy
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
static void EmitMemberInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *MemberInit, const CXXConstructorDecl *Constructor, FunctionArgList &Args)
Represents a C++ struct/union/class.
unsigned getBuiltinID() const
Returns a value indicating whether this function corresponds to a builtin function.
static Destroyer destroyCXXObject
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit)
CGCXXABI & getCXXABI() const
std::string getQualifiedNameAsString() const
static Address ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, CharUnits nonVirtualOffset, llvm::Value *virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase)
Struct with all informations about dynamic [sub]class needed to set vptr.
static RValue get(llvm::Value *V)
ArrayRef< ParmVarDecl * > parameters() const
void EmitDestructorBody(FunctionArgList &Args)
EmitDestructorBody - Emits the body of the current destructor.
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const CXXRecordDecl * VTableClass
unsigned getNumArgs() const
LValue - This represents an lvalue references.
Information for lazily generating a cleanup.
static bool HasTrivialDestructorBody(ASTContext &Context, const CXXRecordDecl *BaseClassDecl, const CXXRecordDecl *MostDerivedClassDecl)
Notes how many arguments were added to the beginning (Prefix) and ending (Suffix) of an arg list...
const LangOptions & getLangOpts() const
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
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 ...
CallArgList - Type for representing both the value and type of arguments in a call.
const LangOptions & getLangOpts() const
base_class_range vbases()
Represents the canonical version of C arrays with a specified constant size.
Declaration of a template function.
static bool FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field)
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
QualType getPointeeType() const
Structure with information about how a bitfield should be accessed.
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
method_range methods() const
QualType getType() const
Retrieves the type of the base class.