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.CreateInBoundsGEP(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)
575 if (!(CD && CD->isCopyOrMoveConstructor()) &&
597 for (
const auto *I : IndirectField->
chain())
611 "Must have member initializer!");
612 assert(MemberInit->
getInit() &&
"Must have initializer!");
616 QualType FieldType = Field->getType();
644 unsigned SrcArgIndex =
669 switch (getEvaluationKind(FieldType)) {
672 EmitExprAsInit(Init, Field, LHS,
false);
675 EmitStoreThroughLValue(RHS, LHS);
679 EmitComplexExprIntoLValue(Init, LHS,
true);
688 overlapForFieldInit(Field),
692 EmitAggExpr(Init, Slot);
700 if (needsEHCleanup(dtorKind))
701 pushEHDestroy(dtorKind, LHS.
getAddress(), FieldType);
759 Prologue ? cast<CXXConstructorDecl>(CurGD.getDecl())->getParent()
760 : cast<CXXDestructorDecl>(CurGD.getDecl())->getParent();
763 struct SizeAndOffset {
768 unsigned PtrSize = CGM.getDataLayout().getPointerSizeInBits();
777 size_t NumFields = 0;
778 for (
const auto *Field : ClassDecl->
fields()) {
780 std::pair<CharUnits, CharUnits> FieldInfo =
783 assert(NumFields < SSV.size());
787 assert(NumFields == SSV.size());
788 if (SSV.size() <= 1)
return;
793 llvm::FunctionType *FTy =
794 llvm::FunctionType::get(CGM.VoidTy, Args,
false);
795 llvm::Constant *F = CGM.CreateRuntimeFunction(
796 FTy, Prologue ?
"__asan_poison_intra_object_redzone" 797 :
"__asan_unpoison_intra_object_redzone");
800 ThisPtr = Builder.CreatePtrToInt(ThisPtr, IntPtrTy);
804 for (
size_t i = 0; i < SSV.size(); i++) {
805 uint64_t AsanAlignment = 8;
806 uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
807 uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
808 uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
809 if (PoisonSize < AsanAlignment || !SSV[i].Size ||
810 (NextField % AsanAlignment) != 0)
813 F, {Builder.CreateAdd(ThisPtr, Builder.getIntN(PtrSize, EndOffset)),
814 Builder.getIntN(PtrSize, PoisonSize)});
820 EmitAsanPrologueOrEpilogue(
true);
824 assert((CGM.getTarget().getCXXABI().hasConstructorVariants() ||
826 "can only generate complete ctor for this ABI");
830 if (CtorType ==
Ctor_Complete && IsConstructorDelegationValid(Ctor) &&
831 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
838 assert(Definition == Ctor &&
"emitting wrong constructor body");
842 bool IsTryBody = (Body && isa<CXXTryStmt>(Body));
844 EnterCXXTryStmt(*cast<CXXTryStmt>(Body),
true);
846 incrementProfileCounter(Body);
855 EmitCtorPrologue(Ctor, CtorType, Args);
859 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
870 ExitCXXTryStmt(*cast<CXXTryStmt>(Body),
true);
878 class CopyingValueRepresentation {
881 : CGF(CGF), OldSanOpts(CGF.
SanOpts) {
885 ~CopyingValueRepresentation() {
895 class FieldMemcpyizer {
899 : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
901 FirstField(
nullptr), LastField(
nullptr), FirstFieldOffset(0),
902 LastFieldOffset(0), LastAddedFieldIndex(0) {}
904 bool isMemcpyableField(
FieldDecl *F)
const {
921 CharUnits getMemcpySize(uint64_t FirstByteOffset)
const {
923 unsigned LastFieldSize =
924 LastField->isBitField()
925 ? LastField->getBitWidthValue(Ctx)
928 uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize -
941 uint64_t FirstByteOffset;
942 if (FirstField->isBitField()) {
950 FirstByteOffset = FirstFieldOffset;
953 CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
969 FirstField =
nullptr;
978 llvm::PointerType *DPT = DestPtr.
getType();
980 llvm::Type::getInt8PtrTy(CGF.
getLLVMContext(), DPT->getAddressSpace());
983 llvm::PointerType *SPT = SrcPtr.
getType();
985 llvm::Type::getInt8PtrTy(CGF.
getLLVMContext(), SPT->getAddressSpace());
994 FirstFieldOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
995 LastFieldOffset = FirstFieldOffset;
1005 "Cannot aggregate fields out of order.");
1011 uint64_t FOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
1012 if (FOffset < FirstFieldOffset) {
1014 FirstFieldOffset = FOffset;
1015 }
else if (FOffset > LastFieldOffset) {
1017 LastFieldOffset = FOffset;
1025 uint64_t FirstFieldOffset, LastFieldOffset;
1026 unsigned LastAddedFieldIndex;
1029 class ConstructorMemcpyizer :
public FieldMemcpyizer {
1044 if (!MemcpyableCtor)
1047 assert(Field &&
"No field for member init.");
1058 if (!isMemcpyableField(Field))
1068 : FieldMemcpyizer(CGF, CD->
getParent(), getTrivialCopySource(CGF, CD, Args)),
1069 ConstructorDecl(CD),
1076 if (isMemberInitMemcpyable(MemberInit)) {
1077 AggregatedInits.push_back(MemberInit);
1078 addMemcpyableField(MemberInit->
getMember());
1080 emitAggregatedInits();
1082 ConstructorDecl, Args);
1086 void emitAggregatedInits() {
1087 if (AggregatedInits.size() <= 1) {
1090 if (!AggregatedInits.empty()) {
1091 CopyingValueRepresentation CVR(CGF);
1093 AggregatedInits[0], ConstructorDecl, Args);
1094 AggregatedInits.clear();
1100 pushEHDestructors();
1102 AggregatedInits.clear();
1105 void pushEHDestructors() {
1110 for (
unsigned i = 0; i < AggregatedInits.size(); ++i) {
1123 emitAggregatedInits();
1128 bool MemcpyableCtor;
1133 class AssignmentMemcpyizer :
public FieldMemcpyizer {
1138 if (!AssignmentsMemcpyable)
1142 if (BO->getOpcode() != BO_Assign)
1148 if (!Field || !isMemcpyableField(Field))
1150 Stmt *RHS = BO->getRHS();
1152 RHS = EC->getSubExpr();
1155 if (
MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
1156 if (ME2->getMemberDecl() == Field)
1168 if (!Field || !isMemcpyableField(Field))
1171 if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->
getMemberDecl()))
1174 }
else if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
1176 if (!FD || FD->
getBuiltinID() != Builtin::BI__builtin_memcpy)
1178 Expr *DstPtr = CE->getArg(0);
1180 DstPtr = DC->getSubExpr();
1182 if (!DUO || DUO->
getOpcode() != UO_AddrOf)
1188 if (!Field || !isMemcpyableField(Field))
1190 Expr *SrcPtr = CE->getArg(1);
1192 SrcPtr = SC->getSubExpr();
1194 if (!SUO || SUO->
getOpcode() != UO_AddrOf)
1197 if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->
getMemberDecl()))
1205 bool AssignmentsMemcpyable;
1211 : FieldMemcpyizer(CGF, AD->
getParent(), Args[Args.size() - 1]),
1213 assert(Args.size() == 2);
1216 void emitAssignment(
Stmt *S) {
1219 addMemcpyableField(F);
1220 AggregatedStmts.push_back(S);
1222 emitAggregatedStmts();
1227 void emitAggregatedStmts() {
1228 if (AggregatedStmts.size() <= 1) {
1229 if (!AggregatedStmts.empty()) {
1230 CopyingValueRepresentation CVR(CGF);
1237 AggregatedStmts.clear();
1241 emitAggregatedStmts();
1248 const auto *BaseClassDecl =
1250 return BaseClassDecl->isDynamicClass();
1259 return EmitDelegatingCXXConstructorCall(CD, Args);
1266 llvm::BasicBlock *BaseCtorContinueBB =
nullptr;
1268 !CGM.getTarget().getCXXABI().hasConstructorVariants()) {
1271 BaseCtorContinueBB =
1272 CGM.getCXXABI().EmitCtorCompleteObjectHandler(*
this, ClassDecl);
1273 assert(BaseCtorContinueBB);
1278 for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
1279 if (CGM.getCodeGenOpts().StrictVTablePointers &&
1280 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1282 CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
1286 if (BaseCtorContinueBB) {
1288 Builder.CreateBr(BaseCtorContinueBB);
1289 EmitBlock(BaseCtorContinueBB);
1293 for (; B != E && (*B)->isBaseInitializer(); B++) {
1294 assert(!(*B)->isBaseVirtual());
1296 if (CGM.getCodeGenOpts().StrictVTablePointers &&
1297 CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1299 CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
1303 CXXThisValue = OldThis;
1305 InitializeVTablePointers(ClassDecl);
1309 ConstructorMemcpyizer CM(*
this, CD, Args);
1310 for (; B != E; B++) {
1314 "Delegating initializer on non-delegating constructor");
1315 CM.addMemberInitializer(Member);
1336 for (
const auto *Field : BaseClassDecl->
fields())
1341 for (
const auto &I : BaseClassDecl->
bases()) {
1346 cast<CXXRecordDecl>(I.getType()->castAs<
RecordType>()->getDecl());
1348 MostDerivedClassDecl))
1352 if (BaseClassDecl == MostDerivedClassDecl) {
1354 for (
const auto &I : BaseClassDecl->
vbases()) {
1356 cast<CXXRecordDecl>(I.getType()->castAs<
RecordType>()->getDecl());
1358 MostDerivedClassDecl))
1397 for (
const auto *Field : ClassDecl->
fields())
1415 llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
1416 TrapCall->setDoesNotReturn();
1417 TrapCall->setDoesNotThrow();
1418 Builder.CreateUnreachable();
1419 Builder.ClearInsertionPoint();
1425 incrementProfileCounter(Body);
1434 if (HaveInsertPoint())
1436 false, LoadCXXThisAddress());
1442 bool isTryBody = (Body && isa<CXXTryStmt>(Body));
1444 EnterCXXTryStmt(*cast<CXXTryStmt>(Body),
true);
1445 EmitAsanPrologueOrEpilogue(
false);
1456 case Dtor_Comdat: llvm_unreachable(
"not expecting a COMDAT");
1457 case Dtor_Deleting: llvm_unreachable(
"already handled deleting case");
1461 "can't emit a dtor without a body for non-Microsoft ABIs");
1467 EmitCXXDestructorCall(Dtor,
Dtor_Base,
false,
1468 false, LoadCXXThisAddress());
1485 if (CGM.getCodeGenOpts().StrictVTablePointers &&
1486 CGM.getCodeGenOpts().OptimizationLevel > 0)
1487 CXXThisValue = Builder.CreateLaunderInvariantGroup(LoadCXXThis());
1488 InitializeVTablePointers(Dtor->
getParent());
1492 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
1496 assert(Dtor->
isImplicit() &&
"bodyless dtor not implicit");
1502 CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
1512 ExitCXXTryStmt(*cast<CXXTryStmt>(Body),
true);
1516 const CXXMethodDecl *AssignOp = cast<CXXMethodDecl>(CurGD.getDecl());
1518 assert(isa<CompoundStmt>(RootS) &&
1519 "Body of an implicit assignment operator should be compound stmt.");
1520 const CompoundStmt *RootCS = cast<CompoundStmt>(RootS);
1524 incrementProfileCounter(RootCS);
1525 AssignmentMemcpyizer AM(*
this, AssignOp, Args);
1526 for (
auto *I : RootCS->
body())
1527 AM.emitAssignment(I);
1547 LoadThisForDtorDelete(CGF, Dtor),
1554 bool ReturnAfterDelete) {
1558 = CGF.
Builder.CreateIsNull(ShouldDeleteCondition);
1559 CGF.
Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
1565 LoadThisForDtorDelete(CGF, Dtor),
1568 ReturnAfterDelete &&
1569 "unexpected value for ReturnAfterDelete");
1570 if (ReturnAfterDelete)
1573 CGF.
Builder.CreateBr(continueBB);
1582 CallDtorDeleteConditional(
llvm::Value *ShouldDeleteCondition)
1583 : ShouldDeleteCondition(ShouldDeleteCondition) {
1584 assert(ShouldDeleteCondition !=
nullptr);
1588 EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition,
1596 bool useEHCleanupForArray;
1600 bool useEHCleanupForArray)
1601 : field(field), destroyer(destroyer),
1602 useEHCleanupForArray(useEHCleanupForArray) {}
1613 flags.isForNormalCleanup() && useEHCleanupForArray);
1623 llvm::ConstantInt::get(CGF.
SizeTy, PoisonSize)};
1627 llvm::FunctionType *FnType =
1628 llvm::FunctionType::get(CGF.
VoidTy, ArgTypes,
false);
1652 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1657 unsigned fieldIndex = 0;
1658 int startIndex = -1;
1665 startIndex = fieldIndex;
1672 }
else if (startIndex >= 0) {
1674 PoisonMembers(CGF, startIndex, fieldIndex);
1688 unsigned layoutEndOffset) {
1693 llvm::ConstantInt *OffsetSizePtr = llvm::ConstantInt::get(
1715 if (PoisonSize == 0)
1718 EmitSanitizerDtorCallback(CGF, OffsetPtr, PoisonSize);
1740 EmitSanitizerDtorCallback(CGF, VTablePtr, PoisonSize);
1754 "Should not emit dtor epilogue for non-exported trivial dtor!");
1760 "operator delete missing - EnterDtorCleanups");
1761 if (CXXStructorImplicitParamValue) {
1765 EmitConditionalDtorDeleteCall(*
this, CXXStructorImplicitParamValue,
1768 EHStack.pushCleanup<CallDtorDeleteConditional>(
1774 LoadThisForDtorDelete(*
this, DD),
1776 EmitBranchThroughCleanup(ReturnBlock);
1794 if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1795 SanOpts.has(SanitizerKind::Memory) && ClassDecl->
getNumVBases() &&
1801 for (
const auto &
Base : ClassDecl->
vbases()) {
1803 = cast<CXXRecordDecl>(
Base.getType()->getAs<
RecordType>()->getDecl());
1820 if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1821 SanOpts.has(SanitizerKind::Memory) && !ClassDecl->
getNumVBases() &&
1826 for (
const auto &
Base : ClassDecl->
bases()) {
1828 if (
Base.isVirtual())
1844 if (CGM.getCodeGenOpts().SanitizeMemoryUseAfterDtor &&
1845 SanOpts.has(SanitizerKind::Memory))
1849 for (
const auto *Field : ClassDecl->
fields()) {
1852 if (!dtorKind)
continue;
1858 CleanupKind cleanupKind = getCleanupKind(dtorKind);
1859 EHStack.pushCleanup<DestroyField>(cleanupKind, Field,
1860 getDestroyer(dtorKind),
1876 bool zeroInitialize) {
1879 emitArrayLength(arrayType, elementType, arrayBegin);
1881 EmitCXXAggrConstructorCall(ctor, numElements, arrayBegin, E,
1882 NewPointerIsChecked, zeroInitialize);
1898 bool NewPointerIsChecked,
1899 bool zeroInitialize) {
1905 llvm::BranchInst *zeroCheckBranch =
nullptr;
1908 llvm::ConstantInt *constantCount
1909 = dyn_cast<llvm::ConstantInt>(numElements);
1910 if (constantCount) {
1912 if (constantCount->isZero())
return;
1916 llvm::BasicBlock *loopBB = createBasicBlock(
"new.ctorloop");
1917 llvm::Value *iszero = Builder.CreateIsNull(numElements,
"isempty");
1918 zeroCheckBranch = Builder.CreateCondBr(iszero, loopBB, loopBB);
1924 llvm::Value *arrayEnd = Builder.CreateInBoundsGEP(arrayBegin, numElements,
1928 llvm::BasicBlock *entryBB = Builder.GetInsertBlock();
1929 llvm::BasicBlock *loopBB = createBasicBlock(
"arrayctor.loop");
1931 llvm::PHINode *cur = Builder.CreatePHI(arrayBegin->getType(), 2,
1933 cur->addIncoming(arrayBegin, entryBB);
1951 EmitNullInitialization(curAddr, type);
1968 Destroyer *destroyer = destroyCXXObject;
1969 pushRegularPartialArrayCleanup(arrayBegin, cur, type, eltAlignment,
1980 Builder.CreateInBoundsGEP(cur, llvm::ConstantInt::get(
SizeTy, 1),
1982 cur->addIncoming(next, Builder.GetInsertBlock());
1985 llvm::Value *done = Builder.CreateICmpEQ(next, arrayEnd,
"arrayctor.done");
1986 llvm::BasicBlock *contBB = createBasicBlock(
"arrayctor.cont");
1987 Builder.CreateCondBr(done, contBB, loopBB);
1990 if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB);
2001 assert(!dtor->isTrivial());
2008 bool ForVirtualBase,
2009 bool Delegating,
Address This,
2012 bool NewPointerIsChecked) {
2022 assert(E->
getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
2025 LValue Src = EmitLValue(Arg);
2027 LValue Dest = MakeAddrLValue(This, DestTy);
2028 EmitAggregateCopyCtor(Dest, Src, Overlap);
2035 ? EvaluationOrder::ForceLeftToRight
2040 EmitCXXConstructorCall(D, Type, ForVirtualBase, Delegating, This, Args,
2041 Overlap, E->
getExprLoc(), NewPointerIsChecked);
2054 if (
P->getType().isDestructedType())
2070 bool ForVirtualBase,
2076 bool NewPointerIsChecked) {
2079 if (!NewPointerIsChecked)
2084 assert(Args.size() == 1 &&
"trivial default ctor with args");
2092 assert(Args.size() == 2 &&
"unexpected argcount for trivial ctor");
2095 Address Src(Args[1].getRValue(*this).getScalarVal(),
2096 getNaturalTypeAlignment(SrcTy));
2097 LValue SrcLVal = MakeAddrLValue(Src, SrcTy);
2099 LValue DestLVal = MakeAddrLValue(This, DestTy);
2100 EmitAggregateCopyCtor(DestLVal, SrcLVal, Overlap);
2104 bool PassPrototypeArgs =
true;
2109 EmitInlinedInheritingCXXConstructorCall(D, Type, ForVirtualBase,
2117 CGM.getCXXABI().addImplicitConstructorArgs(*
this, D, Type, ForVirtualBase,
2121 llvm::Constant *CalleePtr =
2123 const CGFunctionInfo &Info = CGM.getTypes().arrangeCXXConstructorCall(
2124 Args, D, Type, ExtraArgs.
Prefix, ExtraArgs.
Suffix, PassPrototypeArgs);
2139 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2141 CGM.getCXXABI().canSpeculativelyEmitVTable(ClassDecl) &&
2142 CGM.getCodeGenOpts().StrictVTablePointers)
2143 EmitVTableAssumptionLoads(ClassDecl, This);
2153 if (InheritedFromVBase &&
2154 CGM.getTarget().getCXXABI().hasConstructorVariants()) {
2159 Args.push_back(ThisArg);
2160 }
else if (!CXXInheritedCtorInitExprArgs.empty()) {
2162 assert(CXXInheritedCtorInitExprArgs.size() >= D->
getNumParams() &&
2163 "wrong number of parameters for inherited constructor call");
2164 Args = CXXInheritedCtorInitExprArgs;
2168 Args.push_back(ThisArg);
2169 const auto *OuterCtor = cast<CXXConstructorDecl>(CurCodeDecl);
2170 assert(OuterCtor->getNumParams() == D->
getNumParams());
2171 assert(!OuterCtor->isVariadic() &&
"should have been inlined");
2173 for (
const auto *Param : OuterCtor->parameters()) {
2175 OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
2177 EmitDelegateCallArg(Args, Param, E->
getLocation());
2180 if (Param->hasAttr<PassObjectSizeAttr>()) {
2181 auto *POSParam = SizeArguments[Param];
2182 assert(POSParam &&
"missing pass_object_size value for forwarding");
2183 EmitDelegateCallArg(Args, POSParam, E->
getLocation());
2188 EmitCXXConstructorCall(D,
Ctor_Base, ForVirtualBase,
false,
2201 CXXInheritedCtorInitExprArgs = Args;
2204 QualType RetType = BuildFunctionArgList(CurGD, Params);
2208 CGM.getCXXABI().addImplicitConstructorArgs(*
this, Ctor, CtorType,
2209 ForVirtualBase, Delegating, Args);
2212 assert(Args.size() >= Params.size() &&
"too few arguments for call");
2213 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
2214 if (I < Params.size() && isa<ImplicitParamDecl>(Params[I])) {
2215 const RValue &RV = Args[I].getRValue(*
this);
2216 assert(!RV.
isComplex() &&
"complex indirect params not supported");
2220 EmitParmDecl(*Params[I], Val, I + 1);
2228 ReturnValue = CreateIRTemp(RetType,
"retval.inhctor");
2230 CGM.getCXXABI().EmitInstanceFunctionProlog(*
this);
2231 CXXThisValue = CXXABIThisValue;
2234 EmitCtorPrologue(Ctor, CtorType, Params);
2246 if (!NonVirtualOffset.
isZero())
2254 Builder.CreateICmpEQ(VPtrValue, VTableGlobal,
"cmp.vtables");
2255 Builder.CreateAssumption(Cmp);
2260 if (CGM.getCXXABI().doStructorsInitializeVPtrs(ClassDecl))
2261 for (
const VPtr &Vptr : getVTablePointers(ClassDecl))
2262 EmitVTableAssumptionLoad(Vptr, This);
2278 llvm::Type *t = CGM.getTypes().ConvertType(QT);
2279 Src = Builder.CreateBitCast(Src, t);
2299 FunctionArgList::const_iterator I = Args.begin(), E = Args.end();
2300 assert(I != E &&
"no parameters to constructor");
2303 Address This = LoadCXXThisAddress();
2309 if (CGM.getCXXABI().NeedsVTTParameter(CurGD)) {
2310 assert(I != E &&
"cannot skip vtt parameter, already done with args");
2311 assert((*I)->getType()->isPointerType() &&
2312 "skipping parameter not of vtt type");
2317 for (; I != E; ++I) {
2320 EmitDelegateCallArg(DelegateArgs, param, Loc);
2323 EmitCXXConstructorCall(Ctor, CtorType,
false,
2324 true, This, DelegateArgs,
2337 : Dtor(D), Addr(Addr),
Type(Type) {}
2351 Address ThisPtr = LoadCXXThisAddress();
2366 if (CGM.getLangOpts().Exceptions && !ClassDecl->hasTrivialDestructor()) {
2370 EHStack.pushCleanup<CallDelegatingCtorDtor>(
EHCleanup,
2371 ClassDecl->getDestructor(),
2378 bool ForVirtualBase,
2381 CGM.getCXXABI().EmitDestructorCall(*
this, DD, Type, ForVirtualBase,
2391 : Dtor(D), Addr(Addr) {}
2408 if (!ClassDecl)
return;
2412 assert(D && D->
isUsed() &&
"destructor not marked as used!");
2413 PushDestructorCleanup(D, Addr);
2419 CGM.getCXXABI().getVTableAddressPointInStructor(
2422 if (!VTableAddressPoint)
2429 if (CGM.getCXXABI().isVirtualOffsetNeededForVTableField(*
this, Vptr)) {
2433 VirtualOffset = CGM.getCXXABI().GetVirtualBaseClassOffset(
2442 Address VTableField = LoadCXXThisAddress();
2444 if (!NonVirtualOffset.
isZero() || VirtualOffset)
2446 *
this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.
VTableClass,
2452 llvm::FunctionType::get(CGM.Int32Ty,
true)
2455 VTableField = Builder.CreateBitCast(VTableField, VTablePtrTy->getPointerTo());
2456 VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy);
2458 llvm::StoreInst *
Store = Builder.CreateStore(VTableAddressPoint, VTableField);
2459 TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTablePtrTy);
2460 CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
2461 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2462 CGM.getCodeGenOpts().StrictVTablePointers)
2463 CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.
VTableClass);
2473 false, VTableClass, VBases,
2481 bool BaseIsNonVirtualPrimaryBase,
2487 if (!BaseIsNonVirtualPrimaryBase) {
2489 VPtr Vptr = {
Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
2490 Vptrs.push_back(Vptr);
2496 for (
const auto &I : RD->
bases()) {
2498 = cast<CXXRecordDecl>(I.getType()->getAs<
RecordType>()->getDecl());
2506 bool BaseDeclIsNonVirtualPrimaryBase;
2508 if (I.isVirtual()) {
2510 if (!VBases.insert(BaseDecl).second)
2518 BaseDeclIsNonVirtualPrimaryBase =
false;
2523 BaseOffsetFromNearestVBase =
2525 BaseDeclIsNonVirtualPrimaryBase = Layout.
getPrimaryBase() == BaseDecl;
2530 I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
2531 BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
2541 if (CGM.getCXXABI().doStructorsInitializeVPtrs(RD))
2542 for (
const VPtr &Vptr : getVTablePointers(RD))
2543 InitializeVTablePointer(Vptr);
2546 CGM.getCXXABI().initializeHiddenVirtualInheritanceMembers(*
this, RD);
2552 Address VTablePtrSrc = Builder.CreateElementBitCast(This, VTableTy);
2553 llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc,
"vtable");
2554 TBAAAccessInfo TBAAInfo = CGM.getTBAAVTablePtrAccessInfo(VTableTy);
2555 CGM.DecorateInstructionWithTBAA(VTable, TBAAInfo);
2557 if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
2558 CGM.getCodeGenOpts().StrictVTablePointers)
2559 CGM.DecorateInstructionWithInvariantGroup(VTable, RD);
2585 if (MD->isVirtual()) {
2589 if (isa<CXXDestructorDecl>(MD) && MD->isImplicit())
2602 if (SanOpts.has(SanitizerKind::CFIVCall))
2604 else if (CGM.getCodeGenOpts().WholeProgramVTables &&
2605 CGM.HasHiddenLTOVisibility(RD)) {
2606 llvm::Metadata *MD =
2609 llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
2613 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
2614 {CastedVTable, TypeId});
2615 Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
2623 if (!SanOpts.has(SanitizerKind::CFICastStrict))
2626 EmitVTablePtrCheck(RD, VTable, TCK, Loc);
2641 const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassTy->getDecl());
2646 if (!SanOpts.has(SanitizerKind::CFICastStrict))
2649 llvm::BasicBlock *ContBlock =
nullptr;
2653 Builder.CreateIsNotNull(Derived,
"cast.nonnull");
2655 llvm::BasicBlock *CheckBlock = createBasicBlock(
"cast.check");
2656 ContBlock = createBasicBlock(
"cast.cont");
2658 Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
2660 EmitBlock(CheckBlock);
2664 std::tie(VTable, ClassDecl) = CGM.getCXXABI().LoadVTablePtr(
2667 EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
2670 Builder.CreateBr(ContBlock);
2671 EmitBlock(ContBlock);
2679 if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
2680 !CGM.HasHiddenLTOVisibility(RD))
2684 llvm::SanitizerStatKind SSK;
2687 M = SanitizerKind::CFIVCall;
2688 SSK = llvm::SanStat_CFI_VCall;
2691 M = SanitizerKind::CFINVCall;
2692 SSK = llvm::SanStat_CFI_NVCall;
2694 case CFITCK_DerivedCast:
2695 M = SanitizerKind::CFIDerivedCast;
2696 SSK = llvm::SanStat_CFI_DerivedCast;
2698 case CFITCK_UnrelatedCast:
2699 M = SanitizerKind::CFIUnrelatedCast;
2700 SSK = llvm::SanStat_CFI_UnrelatedCast;
2703 case CFITCK_NVMFCall:
2704 case CFITCK_VMFCall:
2705 llvm_unreachable(
"unexpected sanitizer kind");
2709 if (
getContext().getSanitizerBlacklist().isBlacklistedType(M, TypeName))
2713 EmitSanitizerStatReport(SSK);
2715 llvm::Metadata *MD =
2721 CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, TypeId});
2723 llvm::Constant *StaticData[] = {
2724 llvm::ConstantInt::get(
Int8Ty, TCK),
2725 EmitCheckSourceLocation(Loc),
2729 auto CrossDsoTypeId = CGM.CreateCrossDsoCfiTypeId(MD);
2730 if (CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
2731 EmitCfiSlowPathCheck(M, TypeTest, CrossDsoTypeId, CastedVTable, StaticData);
2735 if (CGM.getCodeGenOpts().SanitizeTrap.has(M)) {
2736 EmitTrapCheck(TypeTest);
2740 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
2741 CGM.getLLVMContext(),
2742 llvm::MDString::get(CGM.getLLVMContext(),
"all-vtables"));
2744 CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, AllVtables});
2745 EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
2746 StaticData, {CastedVTable, ValidVtable});
2750 if (!CGM.getCodeGenOpts().WholeProgramVTables ||
2751 !SanOpts.has(SanitizerKind::CFIVCall) ||
2752 !CGM.getCodeGenOpts().SanitizeTrap.has(SanitizerKind::CFIVCall) ||
2753 !CGM.HasHiddenLTOVisibility(RD))
2758 SanitizerKind::CFIVCall, TypeName);
2765 EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
2767 llvm::Metadata *MD =
2769 llvm::Value *TypeId = llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
2773 CGM.getIntrinsic(llvm::Intrinsic::type_checked_load),
2774 {CastedVTable, llvm::ConstantInt::get(
Int32Ty, VTableByteOffset),
2776 llvm::Value *CheckResult = Builder.CreateExtractValue(CheckedLoad, 1);
2778 EmitCheck(std::make_pair(CheckResult, SanitizerKind::CFIVCall),
2779 SanitizerHandler::CFICheckFail,
nullptr,
nullptr);
2781 return Builder.CreateBitCast(
2782 Builder.CreateExtractValue(CheckedLoad, 0),
2783 cast<llvm::PointerType>(VTable->getType())->getElementType());
2791 CGM.getTypes().arrangeCXXMethodDeclaration(callOperator);
2792 llvm::Constant *calleePtr =
2793 CGM.GetAddrOfFunction(
GlobalDecl(callOperator),
2794 CGM.getTypes().GetFunctionType(calleeFnInfo));
2801 if (!resultType->isVoidType() &&
2804 returnSlot =
ReturnValueSlot(ReturnValue, resultType.isVolatileQualified());
2812 RValue RV = EmitCall(calleeFnInfo, callee, returnSlot, callArgs);
2815 if (!resultType->isVoidType() && returnSlot.
isNull()) {
2816 if (
getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
2819 EmitReturnOfRValue(RV, resultType);
2821 EmitBranchThroughCleanup(ReturnBlock);
2825 const BlockDecl *BD = BlockInfo->getBlockDecl();
2834 CGM.ErrorUnsupported(CurCodeDecl,
"lambda conversion to variadic function");
2842 Address ThisPtr = GetAddrOfBlockDecl(variable,
false);
2847 EmitDelegateCallArg(CallArgs, param, param->getLocStart());
2850 "generic lambda interconversion to block not implemented");
2851 EmitForwardingCallToLambda(CallOp, CallArgs);
2866 EmitDelegateCallArg(CallArgs, Param, Param->getLocStart());
2875 void *InsertPos =
nullptr;
2878 assert(CorrespondingCallOpSpecialization);
2879 CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
2881 EmitForwardingCallToLambda(CallOp, CallArgs);
2888 CGM.ErrorUnsupported(MD,
"lambda conversion to variadic function");
2892 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...
Represents a function declaration or definition.
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 ...
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()
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
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined...
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
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.
Represents a variable declaration or definition.
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
const T * getAs() const
Member-template getAs<specific type>'.
const void * Store
Store - This opaque type encapsulates an immutable mapping from locations to values.
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.
void add(RValue rvalue, QualType type)
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
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.
AggValueSlot::Overlap_t overlapForBaseInit(const CXXRecordDecl *RD, const CXXRecordDecl *BaseRD, bool IsVirtual)
Determine whether a base class initialization may overlap some other object.
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.
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, Address This, const CXXConstructExpr *E, AggValueSlot::Overlap_t Overlap, bool NewPointerIsChecked)
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
Represents a member of a struct/union/class.
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 AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
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...
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...
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...
CXXCtorType getCtorType() const
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)
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
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
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.
AggValueSlot::Overlap_t overlapForFieldInit(const FieldDecl *FD)
Determine whether a field initialization may overlap some other object.
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.
Pepresents 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...
void EmitVTableAssumptionLoad(const VPtr &vptr, Address This)
Emit assumption that vptr load == global vtable.
const T * castAs() const
Member-template castAs<specific type>.
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 EmitAsanPrologueOrEpilogue(bool Prologue)
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
The COMDAT used for dtors.
const SanitizerBlacklist & getSanitizerBlacklist() const
GlobalDecl - represents a global declaration.
std::pair< CharUnits, CharUnits > getTypeInfoDataSizeInChars(QualType T) const
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.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
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...
Represents a field injected from an anonymous union/struct into the parent scope. ...
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.
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
bool hasObjCLifetime() 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)
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.
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 information about dynamic [sub]class needed to set vptr.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
static RValue get(llvm::Value *V)
ArrayRef< ParmVarDecl * > parameters() const
void EmitDestructorBody(FunctionArgList &Args)
EmitDestructorBody - Emits the body of the current destructor.
__DEVICE__ int min(int __a, int __b)
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.