29#include "llvm/IR/Intrinsics.h"
30#include "llvm/IR/Metadata.h"
31#include "llvm/Support/SaveAndRestore.h"
32#include "llvm/Transforms/Utils/SanitizerStats.h"
36using namespace CodeGen;
52 return layout.getNonVirtualAlignment();
84 CharUnits expectedVBaseAlign = baseLayout.getNonVirtualAlignment();
97 return std::min(actualBaseAlign, expectedTargetAlign);
100 CharUnits expectedBaseAlign = baseLayout.getNonVirtualAlignment();
120 if (actualBaseAlign >= expectedBaseAlign) {
121 return expectedTargetAlign;
127 return std::min(actualBaseAlign, expectedTargetAlign);
131 assert(
CurFuncDecl &&
"loading 'this' without a func declaration?");
135 if (CXXThisAlignment.
isZero()) {
143 LoadCXXThis(), MD->getFunctionObjectParameterType(), CXXThisAlignment,
156 *
this,
E, base, memberPtr, memberPtrType, IsInBounds);
178 assert(!
Base->isVirtual() &&
"Should not see virtual bases here!");
183 const auto *BaseDecl =
Base->getType()->castAsCXXRecordDecl();
197 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
207 return llvm::ConstantInt::get(
PtrDiffTy, Offset.getQuantity());
219 bool BaseIsVirtual) {
234 if (!Offset.isZero()) {
244 llvm::Value *virtualOffset,
248 assert(!nonVirtualOffset.
isZero() || virtualOffset !=
nullptr);
251 llvm::Value *baseOffset;
252 if (!nonVirtualOffset.
isZero()) {
253 llvm::Type *OffsetType =
259 llvm::ConstantInt::get(OffsetType, nonVirtualOffset.
getQuantity());
261 baseOffset = CGF.
Builder.CreateAdd(virtualOffset, baseOffset);
264 baseOffset = virtualOffset;
275 assert(nearestVBase &&
"virtual offset without vbase?");
277 derivedClass, nearestVBase);
291 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
300 if ((*Start)->isVirtual()) {
301 VBase = (*Start)->getType()->castAsCXXRecordDecl();
309 VBase ? VBase : Derived, Start, PathEnd);
314 if (VBase && Derived->
hasAttr<FinalAttr>()) {
317 NonVirtualOffset += vBaseOffset;
322 llvm::Type *BaseValueTy =
ConvertType((PathEnd[-1])->getType());
323 llvm::Type *PtrTy = llvm::PointerType::get(
331 if (NonVirtualOffset.
isZero() && !VBase) {
334 SkippedChecks.
set(SanitizerKind::Null, !NullCheckValue);
336 DerivedAlign, SkippedChecks);
338 return Value.withElementType(BaseValueTy);
341 llvm::BasicBlock *origBB =
nullptr;
342 llvm::BasicBlock *endBB =
nullptr;
346 if (NullCheckValue) {
347 origBB =
Builder.GetInsertBlock();
352 Builder.CreateCondBr(isNull, endBB, notNullBB);
358 SkippedChecks.
set(SanitizerKind::Null,
true);
360 Value.emitRawPointer(*
this), DerivedTy, DerivedAlign,
365 llvm::Value *VirtualOffset =
nullptr;
373 VirtualOffset, Derived, VBase);
379 if (NullCheckValue) {
380 llvm::BasicBlock *notNullBB =
Builder.GetInsertBlock();
384 llvm::PHINode *PHI =
Builder.CreatePHI(PtrTy, 2,
"cast.result");
385 PHI->addIncoming(
Value.emitRawPointer(*
this), notNullBB);
386 PHI->addIncoming(llvm::Constant::getNullValue(PtrTy), origBB);
398 bool NullCheckValue) {
399 assert(PathBegin != PathEnd &&
"Base path should not be empty!");
402 llvm::Type *DerivedValueTy =
ConvertType(DerivedTy);
404 llvm::Value *NonVirtualOffset =
407 if (!NonVirtualOffset) {
412 llvm::BasicBlock *CastNull =
nullptr;
413 llvm::BasicBlock *CastNotNull =
nullptr;
414 llvm::BasicBlock *CastEnd =
nullptr;
416 if (NullCheckValue) {
433 Addr =
Addr.withElementType(DerivedValueTy);
436 if (NullCheckValue) {
442 llvm::Value *
Value =
Addr.emitRawPointer(*
this);
444 PHI->addIncoming(
Value, CastNotNull);
445 PHI->addIncoming(llvm::Constant::getNullValue(
Value->
getType()), CastNull);
464 uint64_t SubVTTIndex;
469 }
else if (RD ==
Base) {
473 "doing no-op VTT offset in base dtor/ctor?");
474 assert(!ForVirtualBase &&
"Can't have same class as virtual base!");
484 assert(SubVTTIndex != 0 &&
"Sub-VTT index must be greater than zero!");
494 return Builder.CreateConstInBoundsGEP2_64(
495 VTT->getValueType(), VTT, 0, SubVTTIndex);
505 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
514 QualType ThisTy =
D->getFunctionObjectParameterType();
517 DerivedClass, BaseClass,
520 false,
Addr, ThisTy);
538 void VisitCXXThisExpr(
const CXXThisExpr *
E) { UsesThis =
true; }
543 DynamicThisUseChecker Checker(
C);
545 return Checker.UsesThis;
552 "Must have base initializer!");
583 !BaseClassDecl->hasTrivialDestructor())
589 auto *CD = dyn_cast<CXXConstructorDecl>(
D);
590 if (!(CD && CD->isCopyOrMoveConstructor()) &&
591 !
D->isCopyAssignmentOperator() && !
D->isMoveAssignmentOperator())
595 if (
D->isTrivial() && !
D->getParent()->mayInsertExtraPadding())
599 if (
D->getParent()->isUnion() &&
D->isDefaulted())
612 for (
const auto *I : IndirectField->
chain())
627 "Must have member initializer!");
628 assert(MemberInit->
getInit() &&
"Must have initializer!");
632 QualType FieldType = Field->getType();
660 unsigned SrcArgIndex =
684 QualType FieldType = Field->getType();
775 struct SizeAndOffset {
789 size_t NumFields = 0;
790 for (
const auto *Field : ClassDecl->
fields()) {
794 assert(NumFields < SSV.size());
795 SSV[NumFields].Size =
D->isBitField() ? 0 : FieldSize.
getQuantity();
798 assert(NumFields == SSV.size());
799 if (SSV.size() <= 1)
return;
804 llvm::FunctionType *FTy =
805 llvm::FunctionType::get(
CGM.
VoidTy, Args,
false);
807 FTy, Prologue ?
"__asan_poison_intra_object_redzone"
808 :
"__asan_unpoison_intra_object_redzone");
815 for (
size_t i = 0; i < SSV.size(); i++) {
816 uint64_t AsanAlignment = 8;
817 uint64_t NextField = i == SSV.size() - 1 ? TypeSize : SSV[i + 1].Offset;
818 uint64_t PoisonSize = NextField - SSV[i].Offset - SSV[i].Size;
819 uint64_t EndOffset = SSV[i].Offset + SSV[i].Size;
820 if (PoisonSize < AsanAlignment || !SSV[i].Size ||
821 (NextField % AsanAlignment) != 0)
824 F, {
Builder.CreateAdd(ThisPtr,
Builder.getIntN(PtrSize, EndOffset)),
825 Builder.getIntN(PtrSize, PoisonSize)});
837 "can only generate complete ctor for this ABI");
849 assert(
Definition == Ctor &&
"emitting wrong constructor body");
853 bool IsTryBody = isa_and_nonnull<CXXTryStmt>(Body);
871 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
890 class CopyingValueRepresentation {
893 : CGF(CGF), OldSanOpts(CGF.SanOpts) {
897 ~CopyingValueRepresentation() {
907 class FieldMemcpyizer {
911 : CGF(CGF), ClassDecl(ClassDecl), SrcRec(SrcRec),
912 RecLayout(CGF.getContext().getASTRecordLayout(ClassDecl)),
913 FirstField(nullptr), LastField(nullptr), FirstFieldOffset(0),
914 LastFieldOffset(0), LastAddedFieldIndex(0) {}
916 bool isMemcpyableField(
FieldDecl *F)
const {
938 CharUnits getMemcpySize(uint64_t FirstByteOffset)
const {
940 unsigned LastFieldSize =
941 LastField->isBitField()
942 ? LastField->getBitWidthValue()
945 uint64_t MemcpySizeBits = LastFieldOffset + LastFieldSize -
959 if (FirstField->isBitField()) {
967 FirstByteOffset = FirstFieldOffset;
970 CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
987 FirstField =
nullptr;
1005 FirstFieldOffset = RecLayout.getFieldOffset(F->
getFieldIndex());
1006 LastFieldOffset = FirstFieldOffset;
1016 "Cannot aggregate fields out of order.");
1023 if (FOffset < FirstFieldOffset) {
1025 FirstFieldOffset = FOffset;
1026 }
else if (FOffset >= LastFieldOffset) {
1028 LastFieldOffset = FOffset;
1036 uint64_t FirstFieldOffset, LastFieldOffset;
1037 unsigned LastAddedFieldIndex;
1040 class ConstructorMemcpyizer :
public FieldMemcpyizer {
1055 if (!MemcpyableCtor)
1058 assert(Field &&
"No field for member init.");
1069 if (!isMemcpyableField(Field))
1079 : FieldMemcpyizer(CGF, CD->getParent(), getTrivialCopySource(CGF, CD, Args)),
1080 ConstructorDecl(CD),
1081 MemcpyableCtor(CD->isDefaulted() &&
1082 CD->isCopyOrMoveConstructor() &&
1087 if (isMemberInitMemcpyable(MemberInit)) {
1088 AggregatedInits.push_back(MemberInit);
1089 addMemcpyableField(MemberInit->
getMember());
1091 emitAggregatedInits();
1093 ConstructorDecl, Args);
1097 void emitAggregatedInits() {
1098 if (AggregatedInits.size() <= 1) {
1101 if (!AggregatedInits.empty()) {
1102 CopyingValueRepresentation CVR(CGF);
1104 AggregatedInits[0], ConstructorDecl, Args);
1105 AggregatedInits.clear();
1111 pushEHDestructors();
1114 AggregatedInits.clear();
1117 void pushEHDestructors() {
1122 for (
unsigned i = 0; i < AggregatedInits.size(); ++i) {
1135 emitAggregatedInits();
1140 bool MemcpyableCtor;
1145 class AssignmentMemcpyizer :
public FieldMemcpyizer {
1150 if (!AssignmentsMemcpyable)
1154 if (BO->getOpcode() != BO_Assign)
1156 MemberExpr *ME = dyn_cast<MemberExpr>(BO->getLHS());
1160 if (!Field || !isMemcpyableField(Field))
1162 Stmt *RHS = BO->getRHS();
1164 RHS = EC->getSubExpr();
1167 if (
MemberExpr *ME2 = dyn_cast<MemberExpr>(RHS)) {
1168 if (ME2->getMemberDecl() == Field)
1173 CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MCE->getCalleeDecl());
1176 MemberExpr *IOA = dyn_cast<MemberExpr>(MCE->getImplicitObjectArgument());
1180 if (!Field || !isMemcpyableField(Field))
1182 MemberExpr *Arg0 = dyn_cast<MemberExpr>(MCE->getArg(0));
1183 if (!Arg0 || Field != dyn_cast<FieldDecl>(Arg0->
getMemberDecl()))
1186 }
else if (
CallExpr *CE = dyn_cast<CallExpr>(S)) {
1187 FunctionDecl *FD = dyn_cast<FunctionDecl>(CE->getCalleeDecl());
1188 if (!FD || FD->
getBuiltinID() != Builtin::BI__builtin_memcpy)
1192 DstPtr = DC->getSubExpr();
1194 if (!DUO || DUO->
getOpcode() != UO_AddrOf)
1200 if (!Field || !isMemcpyableField(Field))
1204 SrcPtr = SC->getSubExpr();
1206 if (!SUO || SUO->
getOpcode() != UO_AddrOf)
1209 if (!ME2 || Field != dyn_cast<FieldDecl>(ME2->
getMemberDecl()))
1217 bool AssignmentsMemcpyable;
1223 : FieldMemcpyizer(CGF, AD->getParent(), Args[Args.size() - 1]),
1224 AssignmentsMemcpyable(CGF.getLangOpts().getGC() ==
LangOptions::NonGC) {
1225 assert(Args.size() == 2);
1228 void emitAssignment(
Stmt *S) {
1231 addMemcpyableField(F);
1232 AggregatedStmts.push_back(S);
1234 emitAggregatedStmts();
1239 void emitAggregatedStmts() {
1240 if (AggregatedStmts.size() <= 1) {
1241 if (!AggregatedStmts.empty()) {
1242 CopyingValueRepresentation CVR(CGF);
1250 AggregatedStmts.clear();
1254 emitAggregatedStmts();
1284 bool ConstructVBases = CtorType !=
Ctor_Base &&
1291 llvm::BasicBlock *BaseCtorContinueBB =
nullptr;
1292 if (ConstructVBases &&
1294 BaseCtorContinueBB =
1296 assert(BaseCtorContinueBB);
1299 for (; B !=
E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) {
1300 if (!ConstructVBases)
1310 if (BaseCtorContinueBB) {
1312 Builder.CreateBr(BaseCtorContinueBB);
1317 for (; B !=
E && (*B)->isBaseInitializer(); B++) {
1318 assert(!(*B)->isBaseVirtual());
1331 ConstructorMemcpyizer CM(*
this, CD, Args);
1332 for (; B !=
E; B++) {
1334 assert(!
Member->isBaseInitializer());
1335 assert(
Member->isAnyMemberInitializer() &&
1336 "Delegating initializer on non-delegating constructor");
1337 CM.addMemberInitializer(
Member);
1359 for (
const auto *Field : BaseClassDecl->
fields())
1364 for (
const auto &I : BaseClassDecl->
bases()) {
1370 MostDerivedClassDecl))
1374 if (BaseClassDecl == MostDerivedClassDecl) {
1376 for (
const auto &I : BaseClassDecl->
vbases()) {
1377 const auto *
VirtualBase = I.getType()->castAsCXXRecordDecl();
1379 MostDerivedClassDecl))
1394 if (!FieldClassDecl)
1398 if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
1421 for (
const auto *Field : ClassDecl->
fields())
1439 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
1440 TrapCall->setDoesNotReturn();
1441 TrapCall->setDoesNotThrow();
1443 Builder.ClearInsertionPoint();
1470 bool isTryBody = isa_and_nonnull<CXXTryStmt>(Body);
1484 case Dtor_Comdat: llvm_unreachable(
"not expecting a COMDAT");
1485 case Dtor_Deleting: llvm_unreachable(
"already handled deleting case");
1488 assert((Body ||
getTarget().getCXXABI().isMicrosoft()) &&
1489 "can't emit a dtor without a body for non-Microsoft ABIs");
1521 EmitStmt(cast<CXXTryStmt>(Body)->getTryBlock());
1525 assert(Dtor->
isImplicit() &&
"bodyless dtor not implicit");
1531 CurFn->addFnAttr(llvm::Attribute::AlwaysInline);
1547 assert(isa<CompoundStmt>(RootS) &&
1548 "Body of an implicit assignment operator should be compound stmt.");
1549 const CompoundStmt *RootCS = cast<CompoundStmt>(RootS);
1555 AssignmentMemcpyizer AM(*
this, AssignOp, Args);
1556 for (
auto *I : RootCS->
body())
1557 AM.emitAssignment(I);
1578 LoadThisForDtorDelete(CGF, Dtor),
1584 llvm::Value *ShouldDeleteCondition,
1585 bool ReturnAfterDelete) {
1588 llvm::Value *ShouldCallDelete
1590 CGF.
Builder.CreateCondBr(ShouldCallDelete, continueBB, callDeleteBB);
1596 LoadThisForDtorDelete(CGF, Dtor),
1599 ReturnAfterDelete &&
1600 "unexpected value for ReturnAfterDelete");
1601 if (ReturnAfterDelete)
1604 CGF.
Builder.CreateBr(continueBB);
1610 llvm::Value *ShouldDeleteCondition;
1613 CallDtorDeleteConditional(llvm::Value *ShouldDeleteCondition)
1614 : ShouldDeleteCondition(ShouldDeleteCondition) {
1615 assert(ShouldDeleteCondition !=
nullptr);
1619 EmitConditionalDtorDeleteCall(CGF, ShouldDeleteCondition,
1627 bool useEHCleanupForArray;
1631 bool useEHCleanupForArray)
1632 : field(field), destroyer(destroyer),
1633 useEHCleanupForArray(useEHCleanupForArray) {}
1645 flags.isForNormalCleanup() && useEHCleanupForArray);
1649 class DeclAsInlineDebugLocation {
1651 llvm::MDNode *InlinedAt;
1652 std::optional<ApplyDebugLocation> Location;
1656 : DI(CGF.getDebugInfo()) {
1664 ~DeclAsInlineDebugLocation() {
1672 static void EmitSanitizerDtorCallback(
1674 std::optional<CharUnits::QuantityType> PoisonSize = {}) {
1681 if (PoisonSize.has_value()) {
1682 Args.emplace_back(llvm::ConstantInt::get(CGF.
SizeTy, *PoisonSize));
1683 ArgTypes.emplace_back(CGF.
SizeTy);
1686 llvm::FunctionType *FnType =
1687 llvm::FunctionType::get(CGF.
VoidTy, ArgTypes,
false);
1694 EmitSanitizerDtorFieldsCallback(
CodeGenFunction &CGF, llvm::Value *Ptr,
1696 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_fields", Ptr,
1705 : BaseClass(
Base), BaseIsVirtual(BaseIsVirtual) {}
1723 DeclAsInlineDebugLocation InlineHere(CGF, *BaseClass);
1724 EmitSanitizerDtorFieldsCallback(CGF,
Addr.emitRawPointer(CGF),
1728 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1734 unsigned StartIndex;
1740 : Dtor(Dtor), StartIndex(StartIndex), EndIndex(EndIndex) {}
1754 llvm::ConstantInt *OffsetSizePtr =
1757 llvm::Value *OffsetPtr =
1767 CharUnits PoisonSize = PoisonEnd - PoisonStart;
1772 DeclAsInlineDebugLocation InlineHere(
1773 CGF, **std::next(Dtor->getParent()->field_begin(), StartIndex));
1774 EmitSanitizerDtorFieldsCallback(CGF, OffsetPtr, PoisonSize.
getQuantity());
1777 CGF.
CurFn->addFnAttr(
"disable-tail-calls",
"true");
1789 assert(Dtor->getParent()->isDynamicClass());
1796 EmitSanitizerDtorCallback(CGF,
"__sanitizer_dtor_callback_vptr",
1801 class SanitizeDtorCleanupBuilder {
1805 std::optional<unsigned> StartIndex;
1810 : Context(Context), EHStack(EHStack), DD(DD), StartIndex(
std::nullopt) {}
1811 void PushCleanupForField(
const FieldDecl *Field) {
1814 unsigned FieldIndex =
Field->getFieldIndex();
1817 StartIndex = FieldIndex;
1818 }
else if (StartIndex) {
1820 *StartIndex, FieldIndex);
1821 StartIndex = std::nullopt;
1841 "Should not emit dtor epilogue for non-exported trivial dtor!");
1847 "operator delete missing - EnterDtorCleanups");
1848 if (CXXStructorImplicitParamValue) {
1852 EmitConditionalDtorDeleteCall(*
this, CXXStructorImplicitParamValue,
1855 EHStack.pushCleanup<CallDtorDeleteConditional>(
1861 LoadThisForDtorDelete(*
this, DD),
1862 getContext().getCanonicalTagType(ClassDecl));
1888 for (
const auto &
Base : ClassDecl->
vbases()) {
1889 auto *BaseClassDecl =
Base.getType()->castAsCXXRecordDecl();
1890 if (BaseClassDecl->hasTrivialDestructor()) {
1895 SanOpts.
has(SanitizerKind::Memory) && !BaseClassDecl->isEmpty())
1917 for (
const auto &
Base : ClassDecl->
bases()) {
1919 if (
Base.isVirtual())
1943 for (
const auto *Field : ClassDecl->
fields()) {
1945 SanitizeBuilder.PushCleanupForField(Field);
1958 EHStack.pushCleanup<DestroyField>(
1963 SanitizeBuilder.End();
1977 bool zeroInitialize) {
1979 llvm::Value *numElements =
1983 NewPointerIsChecked, zeroInitialize);
1996 llvm::Value *numElements,
1999 bool NewPointerIsChecked,
2000 bool zeroInitialize) {
2006 llvm::BranchInst *zeroCheckBranch =
nullptr;
2009 llvm::ConstantInt *constantCount
2010 = dyn_cast<llvm::ConstantInt>(numElements);
2011 if (constantCount) {
2013 if (constantCount->isZero())
return;
2019 zeroCheckBranch =
Builder.CreateCondBr(iszero, loopBB, loopBB);
2027 elementType, arrayBegin, numElements,
"arrayctor.end");
2030 llvm::BasicBlock *entryBB =
Builder.GetInsertBlock();
2033 llvm::PHINode *cur =
Builder.CreatePHI(arrayBegin->getType(), 2,
2035 cur->addIncoming(arrayBegin, entryBB);
2088 elementType, cur, llvm::ConstantInt::get(
SizeTy, 1),
"arrayctor.next");
2089 cur->addIncoming(next,
Builder.GetInsertBlock());
2092 llvm::Value *done =
Builder.CreateICmpEQ(next, arrayEnd,
"arrayctor.done");
2094 Builder.CreateCondBr(done, contBB, loopBB);
2097 if (zeroCheckBranch) zeroCheckBranch->setSuccessor(0, contBB);
2116 bool ForVirtualBase,
2123 LangAS ThisAS =
D->getFunctionObjectParameterType().getAddressSpace();
2124 llvm::Value *ThisPtr =
2127 if (SlotAS != ThisAS) {
2129 llvm::Type *NewType =
2142 assert(
E->getNumArgs() == 1 &&
"unexpected argcount for trivial ctor");
2144 const Expr *Arg =
E->getArg(0);
2193 bool NewPointerIsChecked, llvm::CallBase **CallOrInvoke) {
2196 if (!NewPointerIsChecked)
2201 if (
D->isTrivial() &&
D->isDefaultConstructor()) {
2202 assert(Args.size() == 1 &&
"trivial default ctor with args");
2210 assert(Args.size() == 2 &&
"unexpected argcount for trivial ctor");
2211 QualType SrcTy =
D->getParamDecl(0)->getType().getNonReferenceType();
2213 Args[1].getRValue(*this).getScalarVal(), SrcTy);
2221 bool PassPrototypeArgs =
true;
2223 if (
auto Inherited =
D->getInheritedConstructor()) {
2267 This,
D->getThisType()->getPointeeType())),
2271 if (InheritedFromVBase &&
2277 Args.push_back(ThisArg);
2278 }
else if (!CXXInheritedCtorInitExprArgs.empty()) {
2280 assert(CXXInheritedCtorInitExprArgs.size() >=
D->getNumParams() &&
2281 "wrong number of parameters for inherited constructor call");
2282 Args = CXXInheritedCtorInitExprArgs;
2286 Args.push_back(ThisArg);
2287 const auto *OuterCtor = cast<CXXConstructorDecl>(
CurCodeDecl);
2288 assert(OuterCtor->getNumParams() ==
D->getNumParams());
2289 assert(!OuterCtor->isVariadic() &&
"should have been inlined");
2291 for (
const auto *Param : OuterCtor->parameters()) {
2293 OuterCtor->getParamDecl(Param->getFunctionScopeIndex())->getType(),
2298 if (Param->hasAttr<PassObjectSizeAttr>()) {
2299 auto *POSParam = SizeArguments[Param];
2300 assert(POSParam &&
"missing pass_object_size value for forwarding");
2308 E->getLocation(),
true);
2320 CXXInheritedCtorInitExprArgs = Args;
2331 assert(Args.size() >= Params.size() &&
"too few arguments for call");
2332 for (
unsigned I = 0, N = Args.size(); I != N; ++I) {
2333 if (I < Params.size() && isa<ImplicitParamDecl>(Params[I])) {
2334 const RValue &RV = Args[I].getRValue(*
this);
2335 assert(!RV.
isComplex() &&
"complex indirect params not supported");
2350 CXXThisValue = CXXABIThisValue;
2357 llvm::Value *VTableGlobal =
2365 if (!NonVirtualOffset.
isZero())
2370 llvm::Value *VPtrValue =
2373 Builder.CreateICmpEQ(VPtrValue, VTableGlobal,
"cmp.vtables");
2374 Builder.CreateAssumption(Cmp);
2400 llvm::Value *SrcVal =
Builder.CreateBitCast(Val, t);
2404 EmitCallArgs(Args, FPT, drop_begin(
E->arguments(), 1),
E->getConstructor(),
2420 FunctionArgList::const_iterator I = Args.begin(),
E = Args.end();
2421 assert(I !=
E &&
"no parameters to constructor");
2426 This, (*I)->getType()->getPointeeType())),
2433 assert(I !=
E &&
"cannot skip vtt parameter, already done with args");
2434 assert((*I)->getType()->isPointerType() &&
2435 "skipping parameter not of vtt type");
2440 for (; I !=
E; ++I) {
2447 true,
This, DelegateArgs,
2465 QualType ThisTy = Dtor->getFunctionObjectParameterType();
2467 true,
Addr, ThisTy);
2504 bool ForVirtualBase,
2535 if (!ClassDecl)
return;
2539 assert(
D &&
D->
isUsed() &&
"destructor not marked as used!");
2545 llvm::Value *VTableAddressPoint =
2549 if (!VTableAddressPoint)
2553 llvm::Value *VirtualOffset =
nullptr;
2570 if (!NonVirtualOffset.
isZero() || VirtualOffset)
2572 *
this, VTableField, NonVirtualOffset, VirtualOffset, Vptr.
VTableClass,
2585 VTableAddressPoint =
2603 false, VTableClass, VBases,
2611 bool BaseIsNonVirtualPrimaryBase,
2617 if (!BaseIsNonVirtualPrimaryBase) {
2619 VPtr Vptr = {
Base, NearestVBase, OffsetFromNearestVBase, VTableClass};
2620 Vptrs.push_back(Vptr);
2626 for (
const auto &I : RD->
bases()) {
2627 auto *BaseDecl = I.getType()->castAsCXXRecordDecl();
2629 if (!BaseDecl->isDynamicClass())
2634 bool BaseDeclIsNonVirtualPrimaryBase;
2636 if (I.isVirtual()) {
2638 if (!VBases.insert(BaseDecl).second)
2646 BaseDeclIsNonVirtualPrimaryBase =
false;
2651 BaseOffsetFromNearestVBase =
2653 BaseDeclIsNonVirtualPrimaryBase = Layout.
getPrimaryBase() == BaseDecl;
2658 I.isVirtual() ? BaseDecl : NearestVBase, BaseOffsetFromNearestVBase,
2659 BaseDeclIsNonVirtualPrimaryBase, VTableClass, VBases, Vptrs);
2678 llvm::Type *VTableTy,
2681 Address VTablePtrSrc =
This.withElementType(VTableTy);
2686 if (
auto AuthenticationInfo =
2689 VTable = cast<llvm::Instruction>(
2740 if (isa<CXXDestructorDecl>(MD) && MD->
isImplicit())
2751 llvm::Value *VTable,
2761 llvm::Value *TypeId =
2769 ? llvm::Intrinsic::type_test
2770 : llvm::Intrinsic::public_type_test;
2771 llvm::Value *TypeTest =
2779static std::pair<SanitizerKind::SanitizerOrdinal, llvm::SanitizerStatKind>
2783 return std::make_pair(SanitizerKind::SO_CFIVCall, llvm::SanStat_CFI_VCall);
2785 return std::make_pair(SanitizerKind::SO_CFINVCall,
2786 llvm::SanStat_CFI_NVCall);
2788 return std::make_pair(SanitizerKind::SO_CFIDerivedCast,
2789 llvm::SanStat_CFI_DerivedCast);
2791 return std::make_pair(SanitizerKind::SO_CFIUnrelatedCast,
2792 llvm::SanStat_CFI_UnrelatedCast);
2796 llvm_unreachable(
"unexpected sanitizer kind");
2798 llvm_unreachable(
"Unknown CFITypeCheckKind enum");
2802 llvm::Value *VTable,
2805 if (!
SanOpts.
has(SanitizerKind::CFICastStrict))
2810 SanitizerHandler::CFICheckFail);
2829 if (!
SanOpts.
has(SanitizerKind::CFICastStrict))
2834 SanitizerHandler::CFICheckFail);
2836 llvm::BasicBlock *ContBlock =
nullptr;
2839 llvm::Value *DerivedNotNull =
2845 Builder.CreateCondBr(DerivedNotNull, CheckBlock, ContBlock);
2850 llvm::Value *VTable;
2851 std::tie(VTable, ClassDecl) =
2863 llvm::Value *VTable,
2875 if (
getContext().getNoSanitizeList().containsType(
2883 llvm::Value *TypeId = llvm::MetadataAsValue::get(
getLLVMContext(), MD);
2885 llvm::Value *TypeTest =
Builder.CreateCall(
2888 llvm::Constant *StaticData[] = {
2889 llvm::ConstantInt::get(
Int8Ty, TCK),
2902 EmitTrapCheck(TypeTest, SanitizerHandler::CFICheckFail, NoMerge);
2906 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
2909 llvm::Value *ValidVtable =
Builder.CreateCall(
2911 EmitCheck(std::make_pair(TypeTest, M), SanitizerHandler::CFICheckFail,
2912 StaticData, {VTable, ValidVtable});
2933 const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy,
2934 uint64_t VTableByteOffset) {
2935 auto CheckOrdinal = SanitizerKind::SO_CFIVCall;
2936 auto CheckHandler = SanitizerHandler::CFICheckFail;
2946 ? llvm::Intrinsic::type_checked_load_relative
2947 : llvm::Intrinsic::type_checked_load;
2948 llvm::Value *CheckedLoad =
Builder.CreateCall(
2950 {VTable, llvm::ConstantInt::get(Int32Ty, VTableByteOffset), TypeId});
2952 llvm::Value *CheckResult =
Builder.CreateExtractValue(CheckedLoad, 1);
2956 !
getContext().getNoSanitizeList().containsType(SanitizerKind::CFIVCall,
2958 EmitCheck(std::make_pair(CheckResult, CheckOrdinal), CheckHandler, {}, {});
2961 return Builder.CreateBitCast(
Builder.CreateExtractValue(CheckedLoad, 0),
2982 if (!resultType->isVoidType() &&
2995 RValue RV =
EmitCall(*calleeFnInfo, callee, returnSlot, callArgs);
2998 if (!resultType->isVoidType() && returnSlot.
isNull()) {
2999 if (
getLangOpts().ObjCAutoRefCount && resultType->isObjCRetainableType()) {
3002 EmitReturnOfRValue(RV, resultType);
3034 "generic lambda interconversion to block not implemented");
3074 void *InsertPos =
nullptr;
3077 assert(CorrespondingCallOpSpecialization);
3078 CallOp = cast<CXXMethodDecl>(CorrespondingCallOpSpecialization);
3082 if (hasInAllocaArg(MD)) {
3084 llvm::Function *ImplFn =
nullptr;
3106 llvm::Value *ThisArg =
CurFn->getArg(0);
3114 llvm::Function **ImplFn) {
3117 llvm::Function *CallOpFn =
3124 ArgTypes.push_back(I->type);
3134 StringRef CallOpName = CallOpFn->getName();
3135 std::string ImplName;
3136 if (
size_t Pos = CallOpName.find_first_of(
"<lambda"))
3137 ImplName = (
"?__impl@" + CallOpName.drop_front(Pos)).str();
3139 ImplName = (
"__impl" + CallOpName).str();
3141 llvm::Function *Fn = CallOpFn->getParent()->getFunction(ImplName);
3144 llvm::GlobalValue::InternalLinkage, ImplName,
3149 const auto *
D = cast<FunctionDecl>(GD.
getDecl());
static Address ApplyNonVirtualAndVirtualOffset(CodeGenFunction &CGF, Address addr, CharUnits nonVirtualOffset, llvm::Value *virtualOffset, const CXXRecordDecl *derivedClass, const CXXRecordDecl *nearestVBase)
static bool canEmitDelegateCallArgs(CodeGenFunction &CGF, const CXXConstructorDecl *Ctor, CXXCtorType Type, CallArgList &Args)
static bool CanSkipVTablePointerInitialization(CodeGenFunction &CGF, const CXXDestructorDecl *Dtor)
CanSkipVTablePointerInitialization - Check whether we need to initialize any vtable pointers before c...
static const CXXRecordDecl * LeastDerivedClassWithSameLayout(const CXXRecordDecl *RD)
static void EmitBaseInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *BaseInit)
static bool isMemcpyEquivalentSpecialMember(const CXXMethodDecl *D)
static std::pair< SanitizerKind::SanitizerOrdinal, llvm::SanitizerStatKind > SanitizerInfoFromCFICheckKind(CodeGenFunction::CFITypeCheckKind TCK)
Converts the CFITypeCheckKind into SanitizerKind::SanitizerOrdinal and llvm::SanitizerStatKind.
static bool BaseInitializerUsesThis(ASTContext &C, const Expr *Init)
static bool FieldHasTrivialDestructorBody(ASTContext &Context, const FieldDecl *Field)
static bool HasTrivialDestructorBody(ASTContext &Context, const CXXRecordDecl *BaseClassDecl, const CXXRecordDecl *MostDerivedClassDecl)
static void EmitMemberInitializer(CodeGenFunction &CGF, const CXXRecordDecl *ClassDecl, CXXCtorInitializer *MemberInit, const CXXConstructorDecl *Constructor, FunctionArgList &Args)
static void EmitLValueForAnyFieldInitialization(CodeGenFunction &CGF, CXXCtorInitializer *MemberInit, LValue &LHS)
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *baseInit)
Defines the C++ template declaration subclasses.
a trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
const NoSanitizeList & getNoSanitizeList() const
TypeInfoChars getTypeInfoDataSizeInChars(QualType T) const
TypeInfoChars getTypeInfoInChars(const Type *T) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
unsigned getTargetAddressSpace(LangAS AS) const
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
CharUnits getSize() const
getSize - Get the record size in characters.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
const CXXRecordDecl * getBase() const
getBase - Returns the base class declaration.
CharUnits getBaseOffset() const
getBaseOffset - Returns the base class offset.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents a block literal declaration, which is like an unnamed FunctionDecl.
capture_const_iterator capture_begin() const
ArrayRef< ParmVarDecl * > parameters() const
Represents a base class of a C++ class.
QualType getType() const
Retrieves the type of the base class.
Represents a call to a C++ constructor.
Expr * getArg(unsigned Arg)
Return the specified argument.
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Represents a C++ constructor within a class.
init_iterator init_end()
Retrieve an iterator past the last initializer.
init_iterator init_begin()
Retrieve an iterator to the first initializer.
bool isDelegatingConstructor() const
Determine whether this constructor is a delegating constructor.
bool isCopyOrMoveConstructor(unsigned &TypeQuals) const
Determine whether this is a copy or move constructor.
CXXCtorInitializer *const * init_const_iterator
Iterates through the member/base initializer list.
Represents a C++ base or member initializer.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
Expr * getInit() const
Get the initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
bool isBaseInitializer() const
Determine whether this initializer is initializing a base class.
bool isIndirectMemberInitializer() const
const Type * getBaseClass() const
If this is a base class initializer, returns the type of the base class.
FieldDecl * getAnyMember() const
IndirectFieldDecl * getIndirectMember() const
bool isBaseVirtual() const
Returns whether the base is virtual or not.
Represents a C++ destructor within a class.
const FunctionDecl * getOperatorDelete() const
Expr * getOperatorDeleteThisArg() const
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a call to a member function that may be written either with member call syntax (e....
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getFunctionObjectParameterType() const
Represents a C++ struct/union/class.
bool isEffectivelyFinal() const
Determine whether it's impossible for a class to be derived from this class.
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
method_range methods() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
base_class_range vbases()
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool isDynamicClass() const
bool hasDefinition() const
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Represents the this expression in C++.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
const CXXBaseSpecifier *const * path_const_iterator
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
bool isPositive() const
isPositive - Test whether the quantity is greater than zero.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
SanitizerSet SanitizeMergeHandlers
Set of sanitizer checks that can merge handlers (smaller code size at the expense of debuggability).
SanitizerSet SanitizeTrap
Set of sanitizer checks that trap rather than diagnose.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::PointerType * getType() const
Return the type of the pointer value.
bool isSanitizerChecked() const
Address getAddress() const
Qualifiers getQualifiers() const
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
static AggValueSlot forAddr(Address addr, Qualifiers quals, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
forAddr - Make a slot for an aggregate value.
Overlap_t mayOverlap() const
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
A scoped helper to set the current debug location to the specified location or preferred location of ...
A scoped helper to set the current debug location to an inlined location.
const BlockDecl * getBlockDecl() const
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
llvm::Value * CreateIsNull(Address Addr, const Twine &Name="")
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateLaunderInvariantGroup(Address Addr)
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual llvm::Value * getVTableAddressPointInStructor(CodeGenFunction &CGF, const CXXRecordDecl *RD, BaseSubobject Base, const CXXRecordDecl *NearestVBase)=0
Get the address point of the vtable for the given base subobject while building a constructor or a de...
virtual void initializeHiddenVirtualInheritanceMembers(CodeGenFunction &CGF, const CXXRecordDecl *RD)
Emit the code to initialize hidden members required to handle virtual inheritance,...
virtual size_t getSrcArgforCopyCtor(const CXXConstructorDecl *, FunctionArgList &Args) const =0
virtual bool isVirtualOffsetNeededForVTableField(CodeGenFunction &CGF, CodeGenFunction::VPtr Vptr)=0
Checks if ABI requires extra virtual offset for vtable field.
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
virtual bool NeedsVTTParameter(GlobalDecl GD)
Return whether the given global decl needs a VTT parameter.
virtual bool canSpeculativelyEmitVTable(const CXXRecordDecl *RD) const =0
Determine whether it's possible to emit a vtable for RD, even though we do not know that the vtable h...
virtual llvm::Constant * getVTableAddressPoint(BaseSubobject Base, const CXXRecordDecl *VTableClass)=0
Get the address point of the vtable for the given base subobject.
virtual std::pair< llvm::Value *, const CXXRecordDecl * > LoadVTablePtr(CodeGenFunction &CGF, Address This, const CXXRecordDecl *RD)=0
Load a vtable from This, an object of polymorphic type RD, or from one of its virtual bases if it doe...
virtual llvm::BasicBlock * EmitCtorCompleteObjectHandler(CodeGenFunction &CGF, const CXXRecordDecl *RD)
virtual bool doStructorsInitializeVPtrs(const CXXRecordDecl *VTableClass)=0
Checks if ABI requires to initialize vptrs for given dynamic class.
virtual llvm::Value * GetVirtualBaseClassOffset(CodeGenFunction &CGF, Address This, const CXXRecordDecl *ClassDecl, const CXXRecordDecl *BaseClassDecl)=0
virtual llvm::Value * EmitMemberDataPointerAddress(CodeGenFunction &CGF, const Expr *E, Address Base, llvm::Value *MemPtr, const MemberPointerType *MPT, bool IsInBounds)
Calculate an l-value from an object and a data member pointer.
virtual void EmitDestructorCall(CodeGenFunction &CGF, const CXXDestructorDecl *DD, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)=0
Emit the destructor call.
AddedStructorArgCounts addImplicitConstructorArgs(CodeGenFunction &CGF, const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, CallArgList &Args)
Add any ABI-specific implicit arguments needed to call a constructor.
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::MDNode * getInlinedAt() const
void setInlinedAt(llvm::MDNode *InlinedAt)
Update the current inline scope.
CGFunctionInfo - Class to encapsulate the information about a function definition.
bool usesInAlloca() const
Return true if this function uses inalloca arguments.
FunctionType::ExtInfo getExtInfo() const
ABIArgInfo & getReturnInfo()
const_arg_iterator arg_begin() const
CanQualType getReturnType() const
const_arg_iterator arg_end() const
RequiredArgs getRequiredArgs() const
CGRecordLayout - This class handles struct and union layout info while lowering AST types to LLVM typ...
const CGBitFieldInfo & getBitFieldInfo(const FieldDecl *FD) const
Return the BitFieldInfo that corresponds to the field FD.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
A scope within which we are constructing the fields of an object which might use a CXXDefaultInitExpr...
static ParamValue forIndirect(Address addr)
static ParamValue forDirect(llvm::Value *value)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * GetVTablePtr(Address This, llvm::Type *VTableTy, const CXXRecordDecl *VTableClass, VTableAuthMode AuthMode=VTableAuthMode::Authenticate)
GetVTablePtr - Return the Value of the vtable pointer member pointed to by This.
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor, const FunctionArgList &Args)
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
AggValueSlot::Overlap_t getOverlapForFieldInit(const FieldDecl *FD)
Determine whether a field initialization may overlap some other object.
void EmitDelegateCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, const FunctionArgList &Args, SourceLocation Loc)
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitAsanPrologueOrEpilogue(bool Prologue)
void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase, bool Delegating, CallArgList &Args)
Emit a call to an inheriting constructor (that is, one that invokes a constructor inherited from a ba...
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
Address LoadCXXThisAddress()
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo)
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)
void pushEHDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushEHDestroy - Push the standard destructor for the given type as an EH-only cleanup.
void EmitVTablePtrCheckForCall(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheckForCall - Virtual method MD is being called via VTable.
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)
void EmitLambdaDelegatingInvokeBody(const CXXMethodDecl *MD, CallArgList &CallArgs)
Address GetAddressOfBaseClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue, SourceLocation Loc)
GetAddressOfBaseClass - This function will add the necessary delta to the load of 'this' and returns ...
LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T)
Given a value of type T* that may not be to a complete object, construct an l-value with the natural ...
void pushRegularPartialArrayCleanup(llvm::Value *arrayBegin, llvm::Value *arrayEnd, QualType elementType, CharUnits elementAlignment, Destroyer *destroyer)
pushRegularPartialArrayCleanup - Push an EH cleanup to destroy already-constructed elements of the gi...
SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack
Stack to track the controlled convergence tokens.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void EmitForwardingCallToLambda(const CXXMethodDecl *LambdaCallOperator, CallArgList &CallArgs, const CGFunctionInfo *CallOpFnInfo=nullptr, llvm::Constant *CallOpFn=nullptr)
llvm::Value * getAsNaturalPointerTo(Address Addr, QualType PointeeType)
void EmitDelegateCallArg(CallArgList &args, const VarDecl *param, SourceLocation loc)
EmitDelegateCallArg - We are performing a delegate call; that is, the current function is delegating ...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
AggValueSlot::Overlap_t getOverlapForBaseInit(const CXXRecordDecl *RD, const CXXRecordDecl *BaseRD, bool IsVirtual)
Determine whether a base class initialization may overlap some other object.
const LangOptions & getLangOpts() const
llvm::Value * EmitARCRetainAutoreleasedReturnValue(llvm::Value *value)
Retain the given object which is the result of a function call.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor)
Checks whether the given constructor is a valid subject for the complete-to-base constructor delegati...
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *VTable, CFITypeCheckKind TCK, SourceLocation Loc)
EmitVTablePtrCheck - Emit a check that VTable is a valid virtual table for RD using llvm....
void EmitConstructorBody(FunctionArgList &Args)
EmitConstructorBody - Emits the body of the current constructor.
const CodeGen::CGBlockInfo * BlockInfo
void EmitAggregateCopyCtor(LValue Dest, LValue Src, AggValueSlot::Overlap_t MayOverlap)
Address makeNaturalAddressForPointer(llvm::Value *Ptr, QualType T, CharUnits Alignment=CharUnits::Zero(), bool ForPointeeType=false, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
Construct an address with the natural alignment of T.
static Destroyer destroyCXXObject
void EmitLambdaInAllocaImplFn(const CXXMethodDecl *CallOp, const CGFunctionInfo **ImplFnInfo, llvm::Function **ImplFn)
void EmitCXXAggrConstructorCall(const CXXConstructorDecl *D, const ArrayType *ArrayTy, Address ArrayPtr, const CXXConstructExpr *E, bool NewPointerIsChecked, bool ZeroInitialization=false)
EmitCXXAggrConstructorCall - Emit a loop to call a particular constructor for each of several members...
VPtrsVector getVTablePointers(const CXXRecordDecl *VTableClass)
void EmitVTablePtrCheckForCast(QualType T, Address Derived, bool MayBeNull, CFITypeCheckKind TCK, SourceLocation Loc)
Derived is the presumed address of an object of type T after a cast.
@ TCK_ConstructorCall
Checking the 'this' pointer for a constructor call.
@ TCK_UpcastToVirtualBase
Checking the operand of a cast to a virtual base object.
@ TCK_Upcast
Checking the operand of a cast to a base object.
void EmitCXXDestructorCall(const CXXDestructorDecl *D, CXXDtorType Type, bool ForVirtualBase, bool Delegating, Address This, QualType ThisTy)
void EmitBranchThroughCleanup(JumpDest Dest)
EmitBranchThroughCleanup - Emit a branch from the current insert block through the normal cleanup han...
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void PushDestructorCleanup(QualType T, Address Addr)
PushDestructorCleanup - Push a cleanup to call the complete-object destructor of an object of the giv...
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
@ ForceLeftToRight
! Language semantics require left-to-right evaluation.
@ Default
! No language constraints on evaluation order.
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field, bool IsInBounds=true)
const TargetInfo & getTarget() const
Address EmitCXXMemberDataPointerAddress(const Expr *E, Address base, llvm::Value *memberPtr, const MemberPointerType *memberPtrType, bool IsInBounds, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Emit the address of a field using a member data pointer.
void maybeCreateMCDCCondBitmap()
Allocate a temp value on the stack that MCDC can use to track condition results.
Address GetAddrOfBlockDecl(const VarDecl *var)
void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type)
EnterDtorCleanups - Enter the cleanups necessary to complete the given phase of destruction for a des...
llvm::Value * EmitPointerAuthSign(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, bool ForVirtualBase, bool Delegating, AggValueSlot ThisAVS, const CXXConstructExpr *E)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This)
Emit assumption load for all bases.
CGDebugInfo * getDebugInfo()
void EmitDestructorBody(FunctionArgList &Args)
EmitDestructorBody - Emits the body of the current destructor.
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...
Address GetAddressOfDirectBaseInCompleteClass(Address Value, const CXXRecordDecl *Derived, const CXXRecordDecl *Base, bool BaseIsVirtual)
GetAddressOfBaseOfCompleteClass - Convert the given pointer to a complete class to the given direct b...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
const TargetCodeGenInfo & getTargetHooks() const
void EmitCtorPrologue(const CXXConstructorDecl *CD, CXXCtorType Type, FunctionArgList &Args)
EmitCtorPrologue - This routine generates necessary code to initialize base classes and non-static da...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
void EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD, llvm::Value *VTable, SourceLocation Loc)
If whole-program virtual table optimization is enabled, emit an assumption that VTable is a member of...
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
llvm::Value * LoadCXXVTT()
LoadCXXVTT - Load the VTT parameter to base constructors/destructors have virtual bases.
void EmitParmDecl(const VarDecl &D, ParamValue Arg, unsigned ArgNo)
EmitParmDecl - Emit a ParmVarDecl or an ImplicitParamDecl.
void EmitInitializerForField(FieldDecl *Field, LValue LHS, Expr *Init)
void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD)
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
CleanupKind getCleanupKind(QualType::DestructionKind kind)
llvm::Type * ConvertTypeForMem(QualType T)
void EmitSynthesizedCXXCopyCtorCall(const CXXConstructorDecl *D, Address This, Address Src, const CXXConstructExpr *E)
void EmitDeleteCall(const FunctionDecl *DeleteFD, llvm::Value *Ptr, QualType DeleteTy, llvm::Value *NumElements=nullptr, CharUnits CookieSize=CharUnits())
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
void EmitLambdaBlockInvokeBody()
void EmitCfiSlowPathCheck(SanitizerKind::SanitizerOrdinal Ordinal, llvm::Value *Cond, llvm::ConstantInt *TypeId, llvm::Value *Ptr, ArrayRef< llvm::Constant * > StaticArgs)
Emit a slow path cross-DSO CFI check which calls __cfi_slowpath if Cond if false.
void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D, bool ForVirtualBase, Address This, bool InheritedFromVBase, const CXXInheritedCtorInitExpr *E)
Emit a call to a constructor inherited from a base class, passing the current constructor's arguments...
RawAddress CreateMemTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen and cas...
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * GetVTTParameter(GlobalDecl GD, bool ForVirtualBase, bool Delegating)
GetVTTParameter - Return the VTT parameter that should be passed to a base constructor/destructor wit...
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void EmitCallArgs(CallArgList &Args, PrototypeWrapper Prototype, llvm::iterator_range< CallExpr::const_arg_iterator > ArgRange, AbstractCallee AC=AbstractCallee(), unsigned ParamsToSkip=0, EvaluationOrder Order=EvaluationOrder::Default)
EmitCallArgs - Emit call arguments for a function.
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCheck(llvm::Value *Checked, SanitizerHandler CheckHandlerID, bool NoMerge=false, const TrapReason *TR=nullptr)
Create a basic block that will call the trap intrinsic, and emit a conditional branch to it,...
llvm::Value * LoadCXXThis()
LoadCXXThis - Load the value of 'this'.
void EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock=false)
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void InitializeVTablePointer(const VPtr &vptr)
Initialize the vtable pointer of the given subobject.
llvm::Value * EmitVTableTypeCheckedLoad(const CXXRecordDecl *RD, llvm::Value *VTable, llvm::Type *VTableTy, uint64_t VTableByteOffset)
Emit a type checked load from the given vtable.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
bool ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD)
Returns whether we should perform a type checked load when loading a virtual function for virtual cal...
llvm::LLVMContext & getLLVMContext()
void InitializeVTablePointers(const CXXRecordDecl *ClassDecl)
void EmitVTableAssumptionLoad(const VPtr &vptr, Address This)
Emit assumption that vptr load == global vtable.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
void EmitExprAsInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
EmitExprAsInit - Emits the code necessary to initialize a location in memory with the given initializ...
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
CodeGenVTables & getVTables()
llvm::ConstantInt * CreateCrossDsoCfiTypeId(llvm::Metadata *MD)
Generate a cross-DSO type identifier for MD.
CharUnits getMinimumClassObjectSize(const CXXRecordDecl *CD)
Returns the minimum object size for an object of the given class type (or a class derived from it).
llvm::Constant * GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty=nullptr, bool ForVTable=false, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the given function.
void DecorateInstructionWithInvariantGroup(llvm::Instruction *I, const CXXRecordDecl *RD)
Adds !invariant.barrier !tag to instruction.
llvm::Constant * getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the constructor/destructor of the given type.
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
llvm::Metadata * CreateMetadataIdentifierForType(QualType T)
Create a metadata identifier for the given type.
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.
bool HasHiddenLTOVisibility(const CXXRecordDecl *RD)
Returns whether the given record has hidden LTO visibility and therefore may participate in (single-m...
const llvm::DataLayout & getDataLayout() const
CharUnits computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, CastExpr::path_const_iterator Start, CastExpr::path_const_iterator End)
TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType)
getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an access to a virtual table poi...
bool shouldEmitConvergenceTokens() const
CGCXXABI & getCXXABI() const
CharUnits getVBaseAlignment(CharUnits DerivedAlign, const CXXRecordDecl *Derived, const CXXRecordDecl *VBase)
Returns the assumed alignment of a virtual base of a class.
CharUnits getClassPointerAlignment(const CXXRecordDecl *CD)
Returns the assumed alignment of an opaque pointer to the given class.
bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD)
Returns whether the given record has public LTO visibility (regardless of -lto-whole-program-visibili...
void DecorateInstructionWithTBAA(llvm::Instruction *Inst, TBAAAccessInfo TBAAInfo)
DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag.
CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, const CXXRecordDecl *Class, CharUnits ExpectedTargetAlign)
Given a class pointer with an actual known alignment, and the expected alignment of an object at a dy...
ItaniumVTableContext & getItaniumVTableContext()
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
std::optional< CGPointerAuthInfo > getVTablePointerAuthInfo(CodeGenFunction *Context, const CXXRecordDecl *Record, llvm::Value *StorageAddress)
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeCXXMethodDeclaration(const CXXMethodDecl *MD)
C++ methods have some special rules and also have implicit parameters.
const CGFunctionInfo & arrangeLLVMFunctionInfo(CanQualType returnType, FnInfoOpts opts, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, ArrayRef< FunctionProtoType::ExtParameterInfo > paramInfos, RequiredArgs args)
"Arrange" the LLVM information for a call or type with the given signature.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
const CGFunctionInfo & arrangeCXXConstructorCall(const CallArgList &Args, const CXXConstructorDecl *D, CXXCtorType CtorKind, unsigned ExtraPrefixArgs, unsigned ExtraSuffixArgs, bool PassProtoArgs=true)
Arrange a call to a C++ method, passing the given arguments.
llvm::GlobalVariable * GetAddrOfVTT(const CXXRecordDecl *RD)
GetAddrOfVTT - Get the address of the VTT for the given record decl.
uint64_t getSubVTTIndex(const CXXRecordDecl *RD, BaseSubobject Base)
getSubVTTIndex - Return the index of the sub-VTT for the base class of the given record decl.
bool useRelativeLayout() const
Return true if the relative vtable layout is used.
Information for lazily generating a cleanup.
A stack of scopes which respond to exceptions, including cleanups and catch blocks.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
bool isVolatileQualified() const
Address getAddress() const
Address getBitFieldAddress() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
An abstract representation of an aligned address.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
CompoundStmt - This represents a group of statements like { stmt stmt }.
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getEndLoc() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
SourceLocation getLocation() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents a member of a struct/union/class.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
Represents a function declaration or definition.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
bool hasTrivialBody() const
Returns whether the function has a trivial body that does not require any specific codegen.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
ArrayRef< ParmVarDecl * > parameters() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isDefaulted() const
Whether this function is defaulted.
Represents a prototype with parameter type info, e.g.
param_type_iterator param_type_begin() const
bool isVariadic() const
Whether this function prototype is variadic.
Declaration of a template function.
FunctionDecl * findSpecialization(ArrayRef< TemplateArgument > Args, void *&InsertPos)
Return the specialization with the provided arguments if it exists, otherwise return the insertion po...
QualType getReturnType() const
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
CXXDtorType getDtorType() const
const Decl * getDecl() const
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
bool isRelativeLayout() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
This represents a decl that may have a name.
std::string getQualifiedNameAsString() const
bool containsType(SanitizerMask Mask, StringRef MangledTypeName, StringRef Category=StringRef()) const
Pointer-authentication qualifiers.
bool isAddressDiscriminated() const
A (possibly-)qualified type.
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
PointerAuthQualifier getPointerAuth() const
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
The collection of all-type qualifiers we support.
bool hasObjCLifetime() const
LangAS getAddressSpace() const
field_range fields() const
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getOriginalDecl() const
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
Stmt - This represents one statement.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool hasConstructorVariants() const
Does this ABI have different entrypoints for complete-object and base-subobject constructors?
bool areArgsDestroyedLeftToRightInCallee() const
Are arguments to a call destroyed left to right in the callee? This is a fundamental language change,...
bool isItaniumFamily() const
Does this ABI generally fall into the Itanium family of ABIs?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
CXXRecordDecl * castAsCXXRecordDecl() const
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents a variable declaration or definition.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
The JSON file list parser is used to communicate input to InstallAPI.
CXXCtorType
C++ constructor types.
@ Ctor_Base
Base object ctor.
@ Ctor_Complete
Complete object ctor.
CXXDtorType
C++ destructor types.
@ Dtor_Comdat
The COMDAT used for dtors.
@ Dtor_Base
Base object dtor.
@ Dtor_Complete
Complete object dtor.
@ Dtor_Deleting
Deleting dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
const FunctionProtoType * T
Structure with information about how a bitfield should be accessed.
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
Similar to AddedStructorArgs, but only notes the number of additional arguments.
Struct with all information about dynamic [sub]class needed to set vptr.
const CXXRecordDecl * NearestVBase
const CXXRecordDecl * VTableClass
CharUnits OffsetFromNearestVBase
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
llvm::IntegerType * PtrDiffTy
CharUnits getPointerAlign() const
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.