40#include "llvm/ADT/STLExtras.h"
41#include "llvm/ADT/ScopeExit.h"
42#include "llvm/ADT/StringExtras.h"
43#include "llvm/IR/Constants.h"
44#include "llvm/IR/DataLayout.h"
45#include "llvm/IR/Intrinsics.h"
46#include "llvm/IR/LLVMContext.h"
47#include "llvm/IR/MDBuilder.h"
48#include "llvm/IR/MatrixBuilder.h"
49#include "llvm/Support/ConvertUTF.h"
50#include "llvm/Support/Endian.h"
51#include "llvm/Support/MathExtras.h"
52#include "llvm/Support/Path.h"
53#include "llvm/Support/xxhash.h"
54#include "llvm/Transforms/Utils/SanitizerStats.h"
67 "ubsan-guard-checks", llvm::cl::Optional,
68 llvm::cl::desc(
"Guard UBSAN checks with `llvm.allow.ubsan.check()`."));
94#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
95 case SanitizerHandler::Enum: \
100 llvm_unreachable(
"unhandled switch case");
108 llvm::Value *ArraySize) {
116 llvm::Value *ArraySize) {
126 llvm::IRBuilderBase::InsertPointGuard IPG(Builder);
143 llvm::Value *ArraySize,
147 *AllocaAddr = Alloca;
148 return MaybeCastStackAddressSpace(Alloca, DestLangAS, ArraySize);
156 llvm::Value *ArraySize) {
157 llvm::AllocaInst *Alloca;
159 Alloca =
Builder.CreateAlloca(Ty, ArraySize, Name);
162 new llvm::AllocaInst(Ty,
CGM.getDataLayout().getAllocaAddrSpace(),
164 if (
SanOpts.Mask & SanitizerKind::Address) {
165 Alloca->addAnnotationMetadata({
"alloca_name_altered", Name.str()});
168 Allocas->Add(Alloca);
203 auto *VectorTy = llvm::FixedVectorType::get(ArrayTy->getElementType(),
204 ArrayTy->getNumElements());
227 PGO->setCurrentStmt(E);
230 return CGM.getCXXABI().EmitMemberPointerIsNotNull(*
this, MemPtr, MPT);
253 if (
const auto *CondOp = dyn_cast<AbstractConditionalOperator>(
276 if (!ignoreResult && aggSlot.
isIgnored())
281 llvm_unreachable(
"bad evaluation kind");
323 llvm_unreachable(
"bad evaluation kind");
346 llvm_unreachable(
"bad evaluation kind");
386 bool Precise = isa_and_nonnull<VarDecl>(VD) &&
387 VD->
hasAttr<ObjCPreciseLifetimeAttr>();
408 llvm_unreachable(
"temporary cannot have dynamic storage duration");
410 llvm_unreachable(
"unknown storage duration");
420 if (
const auto *ClassDecl =
424 ReferenceTemporaryDtor = ClassDecl->getDestructor();
426 if (!ReferenceTemporaryDtor)
429 llvm::FunctionCallee CleanupFn;
430 llvm::Constant *CleanupArg;
436 CleanupArg = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
453 llvm_unreachable(
"temporary cannot have dynamic storage duration");
476 auto *GV =
new llvm::GlobalVariable(
478 llvm::GlobalValue::PrivateLinkage,
Init,
".ref.tmp",
nullptr,
479 llvm::GlobalValue::NotThreadLocal,
483 llvm::Constant *
C = GV;
485 C = TCG.performAddrSpaceCast(
487 llvm::PointerType::get(
491 return RawAddress(
C, GV->getValueType(), alignment);
500 llvm_unreachable(
"temporary can't have dynamic storage duration");
502 llvm_unreachable(
"unknown storage duration");
516 "Reference should never be pseudo-strong!");
524 if (
auto *Var = dyn_cast<llvm::GlobalVariable>(Object.getPointer())) {
526 Object = Object.withElementType(Ty);
534 if (Var->hasInitializer())
537 Var->setInitializer(
CGM.EmitNullConstant(E->
getType()));
543 default: llvm_unreachable(
"expected scalar or aggregate expression");
566 for (
const auto &Ignored : CommaLHSs)
569 if (
const auto *opaque = dyn_cast<OpaqueValueExpr>(E)) {
570 if (opaque->getType()->isRecordType()) {
571 assert(Adjustments.empty());
579 if (
auto *Var = dyn_cast<llvm::GlobalVariable>(
580 Object.getPointer()->stripPointerCasts())) {
582 Object = Object.withElementType(TemporaryType);
586 if (!Var->hasInitializer()) {
587 Var->setInitializer(
CGM.EmitNullConstant(E->
getType()));
592 Object.getAlignment());
608 if (!ShouldEmitLifetimeMarkers)
619 CGBuilderTy::InsertPoint OldIP;
621 ((!
SanOpts.has(SanitizerKind::HWAddress) &&
622 !
SanOpts.has(SanitizerKind::Memory) &&
623 !
CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) ||
625 OldConditional = OutermostConditional;
626 OutermostConditional =
nullptr;
630 Builder.restoreIP(CGBuilderTy::InsertPoint(
631 Block, llvm::BasicBlock::iterator(
Block->back())));
638 if (OldConditional) {
639 OutermostConditional = OldConditional;
656 switch (Adjustment.Kind) {
660 Adjustment.DerivedToBase.BasePath->path_begin(),
661 Adjustment.DerivedToBase.BasePath->path_end(),
669 "materialized temporary field is not a simple lvalue");
677 E, Object, Ptr, Adjustment.Ptr.MPT,
true);
710 const llvm::Constant *Elts) {
718 Builder.CreateMul(Ptr, Builder.getInt64(0xbf58476d1ce4e5b9u));
720 Builder.CreateXor(A0, Builder.CreateLShr(A0, Builder.getInt64(31)));
721 return Builder.CreateXor(Acc, A1);
738 return SanOpts.has(SanitizerKind::Null) ||
739 SanOpts.has(SanitizerKind::Alignment) ||
740 SanOpts.has(SanitizerKind::ObjectSize) ||
741 SanOpts.has(SanitizerKind::Vptr);
748 llvm::Value *ArraySize) {
755 if (Ptr->getType()->getPointerAddressSpace())
766 auto PtrToAlloca = dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCasts());
768 llvm::Value *IsNonNull =
nullptr;
769 bool IsGuaranteedNonNull =
770 SkippedChecks.
has(SanitizerKind::Null) || PtrToAlloca;
772 llvm::BasicBlock *Done =
nullptr;
773 bool DoneViaNullSanitize =
false;
776 auto CheckHandler = SanitizerHandler::TypeMismatch;
778 {SanitizerKind::SO_Null,
779 SanitizerKind::SO_ObjectSize,
780 SanitizerKind::SO_Alignment},
788 if ((
SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
789 !IsGuaranteedNonNull) {
791 IsNonNull =
Builder.CreateIsNotNull(Ptr);
795 IsGuaranteedNonNull = IsNonNull ==
True;
798 if (!IsGuaranteedNonNull) {
799 if (AllowNullPointers) {
803 DoneViaNullSanitize =
true;
805 Builder.CreateCondBr(IsNonNull, Rest, Done);
808 Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null));
813 if (
SanOpts.has(SanitizerKind::ObjectSize) &&
814 !SkippedChecks.
has(SanitizerKind::ObjectSize) &&
816 uint64_t TySize =
CGM.getMinimumObjectSize(Ty).getQuantity();
817 llvm::Value *Size = llvm::ConstantInt::get(
IntPtrTy, TySize);
819 Size =
Builder.CreateMul(Size, ArraySize);
822 llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
823 if (!ConstantSize || !ConstantSize->isNullValue()) {
830 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
832 llvm::Value *NullIsUnknown =
Builder.getFalse();
833 llvm::Value *Dynamic =
Builder.getFalse();
834 llvm::Value *LargeEnough =
Builder.CreateICmpUGE(
835 Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
837 std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize));
841 llvm::MaybeAlign AlignVal;
842 llvm::Value *PtrAsInt =
nullptr;
844 if (
SanOpts.has(SanitizerKind::Alignment) &&
845 !SkippedChecks.
has(SanitizerKind::Alignment)) {
848 AlignVal =
CGM.getNaturalTypeAlignment(Ty,
nullptr,
nullptr,
853 if (AlignVal && *AlignVal > llvm::Align(1) &&
854 (!PtrToAlloca || PtrToAlloca->getAlign() < *AlignVal)) {
856 llvm::Value *Align =
Builder.CreateAnd(
857 PtrAsInt, llvm::ConstantInt::get(
IntPtrTy, AlignVal->value() - 1));
858 llvm::Value *Aligned =
862 std::make_pair(Aligned, SanitizerKind::SO_Alignment));
866 if (Checks.size() > 0) {
867 llvm::Constant *StaticData[] = {
869 llvm::ConstantInt::get(
Int8Ty, AlignVal ? llvm::Log2(*AlignVal) : 1),
870 llvm::ConstantInt::get(
Int8Ty, TCK)};
871 EmitCheck(Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr);
883 if (
SanOpts.has(SanitizerKind::Vptr) &&
886 SanitizerHandler::DynamicTypeCacheMiss);
890 if (!IsGuaranteedNonNull) {
892 IsNonNull =
Builder.CreateIsNotNull(Ptr);
896 Builder.CreateCondBr(IsNonNull, VptrNotNull, Done);
902 llvm::raw_svector_ostream Out(MangledName);
907 if (!
CGM.getContext().getNoSanitizeList().containsType(SanitizerKind::Vptr,
910 llvm::Value *TypeHash =
911 llvm::ConstantInt::get(
Int64Ty, xxh3_64bits(Out.str()));
925 const int CacheSize = 128;
926 llvm::Type *HashTable = llvm::ArrayType::get(
IntPtrTy, CacheSize);
927 llvm::Value *
Cache =
CGM.CreateRuntimeVariable(HashTable,
928 "__ubsan_vptr_type_cache");
929 llvm::Value *Slot =
Builder.CreateAnd(Hash,
932 llvm::Value *Indices[] = {
Builder.getInt32(0), Slot };
933 llvm::Value *CacheVal =
Builder.CreateAlignedLoad(
941 llvm::Value *EqualHash =
Builder.CreateICmpEQ(CacheVal, Hash);
942 llvm::Constant *StaticData[] = {
946 llvm::ConstantInt::get(
Int8Ty, TCK)
948 llvm::Value *DynamicData[] = { Ptr, Hash };
949 EmitCheck(std::make_pair(EqualHash, SanitizerKind::SO_Vptr),
950 SanitizerHandler::DynamicTypeCacheMiss, StaticData,
958 {DoneViaNullSanitize ? SanitizerKind::SO_Null : SanitizerKind::SO_Vptr},
959 DoneViaNullSanitize ? SanitizerHandler::TypeMismatch
960 : SanitizerHandler::DynamicTypeCacheMiss);
969 uint64_t EltSize =
C.getTypeSizeInChars(EltTy).getQuantity();
977 auto *ParamDecl = dyn_cast<ParmVarDecl>(ArrayDeclRef->getDecl());
981 auto *POSAttr = ParamDecl->getAttr<PassObjectSizeAttr>();
986 int POSType = POSAttr->getType();
987 if (POSType != 0 && POSType != 1)
991 auto PassedSizeIt = SizeArguments.find(ParamDecl);
992 if (PassedSizeIt == SizeArguments.end())
996 assert(LocalDeclMap.count(PassedSizeDecl) &&
"Passed size not loadable");
997 Address AddrOfSize = LocalDeclMap.find(PassedSizeDecl)->second;
1000 llvm::Value *SizeOfElement =
1001 llvm::ConstantInt::get(SizeInBytes->getType(), EltSize);
1002 return Builder.CreateUDiv(SizeInBytes, SizeOfElement);
1011 StrictFlexArraysLevel) {
1014 IndexedType =
Base->getType();
1015 return CGF.
Builder.getInt32(VT->getNumElements());
1020 if (
const auto *CE = dyn_cast<CastExpr>(
Base)) {
1021 if (CE->getCastKind() == CK_ArrayToPointerDecay &&
1022 !CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.
getContext(),
1023 StrictFlexArraysLevel)) {
1026 IndexedType = CE->getSubExpr()->getType();
1028 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
1029 return CGF.
Builder.getInt(CAT->getSize());
1031 if (
const auto *VAT = dyn_cast<VariableArrayType>(AT))
1039 QualType EltTy{
Base->getType()->getPointeeOrArrayElementType(), 0};
1041 IndexedType =
Base->getType();
1066class StructAccessBase
1067 :
public ConstStmtVisitor<StructAccessBase, const Expr *> {
1068 const RecordDecl *ExpectedRD;
1070 bool IsExpectedRecordDecl(
const Expr *E)
const {
1078 StructAccessBase(
const RecordDecl *ExpectedRD) : ExpectedRD(ExpectedRD) {}
1097 const Expr *Visit(
const Expr *E) {
1098 return ConstStmtVisitor<StructAccessBase, const Expr *>::Visit(E);
1101 const Expr *VisitStmt(
const Stmt *S) {
return nullptr; }
1116 const Expr *VisitDeclRefExpr(
const DeclRefExpr *E) {
1117 return IsExpectedRecordDecl(E) ? E :
nullptr;
1119 const Expr *VisitMemberExpr(
const MemberExpr *E) {
1120 if (IsExpectedRecordDecl(E) && E->
isArrow())
1122 const Expr *Res = Visit(E->
getBase());
1123 return !Res && IsExpectedRecordDecl(E) ? E : Res;
1125 const Expr *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
1126 return IsExpectedRecordDecl(E) ? E :
nullptr;
1128 const Expr *VisitCallExpr(
const CallExpr *E) {
1129 return IsExpectedRecordDecl(E) ? E :
nullptr;
1132 const Expr *VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
1133 if (IsExpectedRecordDecl(E))
1137 const Expr *VisitCastExpr(
const CastExpr *E) {
1139 return IsExpectedRecordDecl(E) ? E :
nullptr;
1142 const Expr *VisitParenExpr(
const ParenExpr *E) {
1145 const Expr *VisitUnaryAddrOf(
const UnaryOperator *E) {
1148 const Expr *VisitUnaryDeref(
const UnaryOperator *E) {
1161 int64_t FieldNo = -1;
1170 Indices.emplace_back(CGF.
Builder.getInt32(FieldNo));
1179 Indices.emplace_back(CGF.
Builder.getInt32(FieldNo));
1193 const Expr *StructBase = StructAccessBase(RD).Visit(
Base);
1197 llvm::Value *Res =
nullptr;
1202 Res =
Addr.emitRawPointer(*
this);
1203 }
else if (StructBase->
isLValue()) {
1206 Res =
Addr.emitRawPointer(*
this);
1213 if (Indices.empty())
1216 Indices.push_back(
Builder.getInt32(0));
1240 const Expr *ArrayExprBase,
1241 llvm::Value *IndexVal,
QualType IndexType,
1243 assert(
SanOpts.has(SanitizerKind::ArrayBounds) &&
1244 "should not be called unless adding bounds checks");
1249 *
this, ArrayExprBase, ArrayExprBaseType, StrictFlexArraysLevel);
1252 BoundsVal,
getContext().getSizeType(), Accessed);
1257 llvm::Value *IndexVal,
1259 llvm::Value *BoundsVal,
1260 QualType BoundsType,
bool Accessed) {
1264 auto CheckKind = SanitizerKind::SO_ArrayBounds;
1265 auto CheckHandler = SanitizerHandler::OutOfBounds;
1277 llvm::Value *IndexInst =
Builder.CreateIntCast(IndexVal, Ty, IndexSigned);
1278 llvm::Value *BoundsInst =
Builder.CreateIntCast(BoundsVal, Ty,
false);
1280 llvm::Constant *StaticData[] = {
1286 llvm::Value *Check = Accessed ?
Builder.CreateICmpULT(IndexInst, BoundsInst)
1287 :
Builder.CreateICmpULE(IndexInst, BoundsInst);
1291 llvm::Value *Cmp =
Builder.CreateICmpSGT(
1292 BoundsVal, llvm::ConstantInt::get(BoundsVal->getType(), 0));
1293 Check =
Builder.CreateAnd(Cmp, Check);
1296 EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData,
1306 auto *TypeNameMD = MDB.createString(ATMD->TypeName);
1307 auto *ContainsPtrC =
Builder.getInt1(ATMD->ContainsPointer);
1308 auto *ContainsPtrMD = MDB.createConstant(ContainsPtrC);
1311 return llvm::MDNode::get(
CGM.getLLVMContext(), {TypeNameMD, ContainsPtrMD});
1315 assert(
SanOpts.has(SanitizerKind::AllocToken) &&
1316 "Only needed with -fsanitize=alloc-token");
1317 CB->setMetadata(llvm::LLVMContext::MD_alloc_token,
1329 assert(
SanOpts.has(SanitizerKind::AllocToken) &&
1330 "Only needed with -fsanitize=alloc-token");
1332 CB->setMetadata(llvm::LLVMContext::MD_alloc_token, MDN);
1337 bool isInc,
bool isPre) {
1340 llvm::Value *NextVal;
1342 uint64_t AmountVal = isInc ? 1 : -1;
1343 NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal,
true);
1346 NextVal =
Builder.CreateAdd(InVal.first, NextVal, isInc ?
"inc" :
"dec");
1349 llvm::APFloat FVal(
getContext().getFloatTypeSemantics(ElemTy), 1);
1355 NextVal =
Builder.CreateFAdd(InVal.first, NextVal, isInc ?
"inc" :
"dec");
1363 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*
this,
1368 return isPre ? IncVal : InVal;
1378 DI->EmitExplicitCastType(E->
getType());
1389 if (
auto *constantIdx = dyn_cast<llvm::ConstantInt>(idx)) {
1390 CharUnits offset = constantIdx->getZExtValue() * eltSize;
1404 assert(BO->
isAdditiveOp() &&
"Expect an addition or subtraction.");
1407 bool isSubtraction = BO->
getOpcode() == BO_Sub;
1410 llvm::Value *
index =
nullptr;
1414 std::swap(pointerOperand, indexOperand);
1426 BO, pointerOperand, pointer, indexOperand,
index, isSubtraction);
1433 nullptr, IsKnownNonNull);
1446 if (
const CastExpr *CE = dyn_cast<CastExpr>(E)) {
1447 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(CE))
1450 switch (CE->getCastKind()) {
1454 case CK_AddressSpaceConversion:
1455 if (
auto PtrTy = CE->getSubExpr()->getType()->getAs<
PointerType>()) {
1456 if (PtrTy->getPointeeType()->isVoidType())
1462 CE->getSubExpr(), &InnerBaseInfo, &InnerTBAAInfo, IsKnownNonNull);
1463 if (BaseInfo) *BaseInfo = InnerBaseInfo;
1464 if (TBAAInfo) *TBAAInfo = InnerTBAAInfo;
1470 E->
getType(), &TargetTypeBaseInfo, &TargetTypeTBAAInfo);
1478 BaseInfo->mergeForCast(TargetTypeBaseInfo);
1479 Addr.setAlignment(Align);
1483 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast) &&
1484 CE->getCastKind() == CK_BitCast) {
1492 llvm::Type *ElemTy =
1494 Addr =
Addr.withElementType(ElemTy);
1495 if (CE->getCastKind() == CK_AddressSpaceConversion)
1505 case CK_ArrayToPointerDecay:
1509 case CK_UncheckedDerivedToBase:
1510 case CK_DerivedToBase: {
1517 CE->getSubExpr(), BaseInfo,
nullptr,
1519 CE->getCastKind() == CK_UncheckedDerivedToBase));
1520 auto Derived = CE->getSubExpr()->
getType()->getPointeeCXXRecordDecl();
1522 Addr, Derived, CE->path_begin(), CE->path_end(),
1535 if (UO->getOpcode() == UO_AddrOf) {
1536 LValue LV = CGF.
EmitLValue(UO->getSubExpr(), IsKnownNonNull);
1537 if (BaseInfo) *BaseInfo = LV.getBaseInfo();
1538 if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
1539 return LV.getAddress();
1544 if (
auto *
Call = dyn_cast<CallExpr>(E)) {
1545 switch (
Call->getBuiltinCallee()) {
1548 case Builtin::BIaddressof:
1549 case Builtin::BI__addressof:
1550 case Builtin::BI__builtin_addressof: {
1552 if (BaseInfo) *BaseInfo = LV.getBaseInfo();
1553 if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
1554 return LV.getAddress();
1560 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
1561 if (BO->isAdditiveOp())
1570 true, BaseInfo, TBAAInfo, IsKnownNonNull);
1580 if (IsKnownNonNull && !
Addr.isKnownNonNull())
1581 Addr.setKnownNonNull();
1588 return CGM.getCXXABI().EmitMemberPointerIsNotNull(*
this,
V, MPT);
1589 return Builder.CreateICmpNE(
V, llvm::Constant::getNullValue(
V->getType()));
1600 llvm::Value *
U = llvm::UndefValue::get(EltTy);
1615 llvm_unreachable(
"bad evaluation kind");
1640 if (
const auto *CE = dyn_cast<CastExpr>(
Base)) {
1641 Base = CE->getSubExpr();
1642 }
else if (
const auto *PE = dyn_cast<ParenExpr>(
Base)) {
1643 Base = PE->getSubExpr();
1644 }
else if (
const auto *UO = dyn_cast<UnaryOperator>(
Base)) {
1645 if (UO->getOpcode() == UO_Extension)
1646 Base = UO->getSubExpr();
1664 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
1667 SkippedChecks.
set(SanitizerKind::Alignment,
true);
1669 SkippedChecks.
set(SanitizerKind::Null,
true);
1696 CGM.runWithSufficientStackSpace(
1697 E->
getExprLoc(), [&] { LV = EmitLValueHelper(E, IsKnownNonNull); });
1709 return cast<CallExpr>(SE)->getCallReturnType(Ctx)->getPointeeType();
1712LValue CodeGenFunction::EmitLValueHelper(
const Expr *E,
1714 ApplyDebugLocation DL(*
this, E);
1718 case Expr::ObjCPropertyRefExprClass:
1719 llvm_unreachable(
"cannot emit a property reference directly");
1721 case Expr::ObjCSelectorExprClass:
1723 case Expr::ObjCIsaExprClass:
1725 case Expr::BinaryOperatorClass:
1727 case Expr::CompoundAssignOperatorClass: {
1729 if (
const AtomicType *AT = Ty->
getAs<AtomicType>())
1730 Ty = AT->getValueType();
1735 case Expr::CallExprClass:
1736 case Expr::CXXMemberCallExprClass:
1737 case Expr::CXXOperatorCallExprClass:
1738 case Expr::UserDefinedLiteralClass:
1740 case Expr::CXXRewrittenBinaryOperatorClass:
1743 case Expr::VAArgExprClass:
1745 case Expr::DeclRefExprClass:
1747 case Expr::ConstantExprClass: {
1749 if (llvm::Value *
Result = ConstantEmitter(*this).tryEmitConstantExpr(CE)) {
1755 case Expr::ParenExprClass:
1757 case Expr::GenericSelectionExprClass:
1760 case Expr::PredefinedExprClass:
1762 case Expr::StringLiteralClass:
1764 case Expr::ObjCEncodeExprClass:
1766 case Expr::PseudoObjectExprClass:
1768 case Expr::InitListExprClass:
1770 case Expr::CXXTemporaryObjectExprClass:
1771 case Expr::CXXConstructExprClass:
1773 case Expr::CXXBindTemporaryExprClass:
1775 case Expr::CXXUuidofExprClass:
1777 case Expr::LambdaExprClass:
1780 case Expr::ExprWithCleanupsClass: {
1783 LValue LV =
EmitLValue(cleanups->getSubExpr(), IsKnownNonNull);
1784 if (LV.isSimple()) {
1787 Address
Addr = LV.getAddress();
1788 llvm::Value *
V =
Addr.getBasePointer();
1789 Scope.ForceCleanup({&
V});
1790 Addr.replaceBasePointer(
V);
1792 LV.getBaseInfo(), LV.getTBAAInfo());
1799 case Expr::CXXDefaultArgExprClass: {
1802 return EmitLValue(DAE->getExpr(), IsKnownNonNull);
1804 case Expr::CXXDefaultInitExprClass: {
1807 return EmitLValue(DIE->getExpr(), IsKnownNonNull);
1809 case Expr::CXXTypeidExprClass:
1812 case Expr::ObjCMessageExprClass:
1814 case Expr::ObjCIvarRefExprClass:
1816 case Expr::StmtExprClass:
1818 case Expr::UnaryOperatorClass:
1820 case Expr::ArraySubscriptExprClass:
1822 case Expr::MatrixSingleSubscriptExprClass:
1824 case Expr::MatrixSubscriptExprClass:
1826 case Expr::ArraySectionExprClass:
1828 case Expr::ExtVectorElementExprClass:
1830 case Expr::CXXThisExprClass:
1832 case Expr::MemberExprClass:
1834 case Expr::CompoundLiteralExprClass:
1836 case Expr::ConditionalOperatorClass:
1838 case Expr::BinaryConditionalOperatorClass:
1840 case Expr::ChooseExprClass:
1842 case Expr::OpaqueValueExprClass:
1844 case Expr::SubstNonTypeTemplateParmExprClass:
1847 case Expr::ImplicitCastExprClass:
1848 case Expr::CStyleCastExprClass:
1849 case Expr::CXXFunctionalCastExprClass:
1850 case Expr::CXXStaticCastExprClass:
1851 case Expr::CXXDynamicCastExprClass:
1852 case Expr::CXXReinterpretCastExprClass:
1853 case Expr::CXXConstCastExprClass:
1854 case Expr::CXXAddrspaceCastExprClass:
1855 case Expr::ObjCBridgedCastExprClass:
1858 case Expr::MaterializeTemporaryExprClass:
1861 case Expr::CoawaitExprClass:
1863 case Expr::CoyieldExprClass:
1865 case Expr::PackIndexingExprClass:
1867 case Expr::HLSLOutArgExprClass:
1868 llvm_unreachable(
"cannot emit a HLSL out argument directly");
1875 assert(
type.isCanonical());
1876 assert(!
type->isReferenceType());
1884 if (
const auto *RT = dyn_cast<RecordType>(
type))
1885 if (
const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
1886 RD = RD->getDefinitionOrSelf();
1887 if (RD->hasMutableFields() || !RD->isTrivial())
1909 if (
const auto *ref = dyn_cast<ReferenceType>(
type)) {
1933 }
else if (
const auto *var = dyn_cast<VarDecl>(
Value)) {
1943 bool resultIsReference;
1949 resultIsReference =
false;
1955 resultIsReference =
true;
1976 auto *MD = dyn_cast_or_null<CXXMethodDecl>(
CurCodeDecl);
1977 if (
isLambdaMethod(MD) && MD->getOverloadedOperator() == OO_Call) {
1980 if (
const VarDecl *VD = dyn_cast<const VarDecl>(D)) {
1981 if (!VD->hasAttr<CUDADeviceAttr>()) {
2004 if (resultIsReference)
2031 assert(Constant &&
"not a constant");
2047 llvm::APInt &
Min, llvm::APInt &End,
2048 bool StrictEnums,
bool IsBool) {
2050 bool IsRegularCPlusPlusEnum =
2051 CGF.
getLangOpts().CPlusPlus && StrictEnums && ED && !ED->isFixed();
2052 if (!IsBool && !IsRegularCPlusPlusEnum)
2059 ED->getValueRange(End,
Min);
2064llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
2065 llvm::APInt
Min, End;
2071 return MDHelper.createRange(
Min, End);
2079 }
else if (
CGM.getCodeGenOpts().OptimizationLevel > 0) {
2080 if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) {
2081 Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
2082 Load->setMetadata(llvm::LLVMContext::MD_noundef,
2083 llvm::MDNode::get(
CGM.getLLVMContext(), {}));
2090 bool HasBoolCheck =
SanOpts.has(SanitizerKind::Bool);
2091 bool HasEnumCheck =
SanOpts.has(SanitizerKind::Enum);
2092 if (!HasBoolCheck && !HasEnumCheck)
2097 bool NeedsBoolCheck = HasBoolCheck && IsBool;
2099 if (!NeedsBoolCheck && !NeedsEnumCheck)
2109 if (NeedsEnumCheck &&
2110 getContext().isTypeIgnoredBySanitizer(SanitizerKind::Enum, Ty))
2113 llvm::APInt
Min, End;
2118 NeedsEnumCheck ? SanitizerKind::SO_Enum : SanitizerKind::SO_Bool;
2121 auto CheckHandler = SanitizerHandler::LoadInvalidValue;
2126 Check =
Builder.CreateICmpULE(
Value, llvm::ConstantInt::get(Ctx, End));
2128 llvm::Value *Upper =
2129 Builder.CreateICmpSLE(
Value, llvm::ConstantInt::get(Ctx, End));
2130 llvm::Value *Lower =
2132 Check =
Builder.CreateAnd(Upper, Lower);
2136 EmitCheck(std::make_pair(Check, Kind), CheckHandler, StaticArgs,
Value);
2145 bool isNontemporal) {
2146 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
Addr.getBasePointer()))
2147 if (GV->isThreadLocal())
2153 if (ClangVecTy->isPackedVectorBoolType(
getContext())) {
2155 unsigned ValNumElems =
2158 auto *RawIntV =
Builder.CreateLoad(
Addr, Volatile,
"load_bits");
2159 const auto *RawIntTy = RawIntV->getType();
2160 assert(RawIntTy->isIntegerTy() &&
"compressed iN storage for bitvectors");
2162 auto *PaddedVecTy = llvm::FixedVectorType::get(
2163 Builder.getInt1Ty(), RawIntTy->getPrimitiveSizeInBits());
2164 llvm::Value *
V =
Builder.CreateBitCast(RawIntV, PaddedVecTy);
2177 if (VTy != NewVecTy) {
2179 llvm::Value *
V =
Builder.CreateLoad(Cast, Volatile,
"loadVecN");
2180 unsigned OldNumElements = VTy->getNumElements();
2182 std::iota(Mask.begin(), Mask.end(), 0);
2183 V =
Builder.CreateShuffleVector(
V, Mask,
"extractVec");
2198 llvm::LoadInst *Load =
Builder.CreateLoad(
Addr, Volatile);
2199 if (isNontemporal) {
2200 llvm::MDNode *Node = llvm::MDNode::get(
2201 Load->getContext(), llvm::ConstantAsMetadata::get(
Builder.getInt32(1)));
2202 Load->setMetadata(llvm::LLVMContext::MD_nontemporal, Node);
2205 CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
2217 Ty = AtomicTy->getValueType();
2221 if (StoreTy->isVectorTy() && StoreTy->getScalarSizeInBits() >
2226 unsigned MemNumElems = StoreTy->getPrimitiveSizeInBits();
2247 Ty = AtomicTy->getValueType();
2253 auto *PaddedVecTy = llvm::FixedVectorType::get(
2254 Builder.getInt1Ty(), RawIntTy->getPrimitiveSizeInBits());
2274 bool IsVector =
true) {
2275 auto *ArrayTy = dyn_cast<llvm::ArrayType>(
Addr.getElementType());
2276 if (ArrayTy && IsVector) {
2277 auto *VectorTy = llvm::FixedVectorType::get(ArrayTy->getElementType(),
2278 ArrayTy->getNumElements());
2280 return Addr.withElementType(VectorTy);
2282 auto *VectorTy = dyn_cast<llvm::VectorType>(
Addr.getElementType());
2283 if (VectorTy && !IsVector) {
2284 auto *ArrayTy = llvm::ArrayType::get(
2285 VectorTy->getElementType(),
2288 return Addr.withElementType(ArrayTy);
2300 value->getType()->isVectorTy());
2302 lvalue.getBaseInfo(), lvalue.getTBAAInfo(), isInit,
2303 lvalue.isNontemporal());
2310 bool isInit,
bool isNontemporal) {
2311 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
Addr.getBasePointer()))
2312 if (GV->isThreadLocal())
2320 if (
auto *VecTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2322 CGM.getABIInfo().getOptimalVectorMemoryType(VecTy,
getLangOpts());
2323 if (!ClangVecTy->isPackedVectorBoolType(
getContext()) &&
2324 VecTy != NewVecTy) {
2326 VecTy->getNumElements());
2327 std::iota(Mask.begin(), Mask.begin() + VecTy->getNumElements(), 0);
2331 Mask,
"extractVec");
2334 if (
Addr.getElementType() != SrcTy)
2335 Addr =
Addr.withElementType(SrcTy);
2352 if (isNontemporal) {
2353 llvm::MDNode *Node =
2354 llvm::MDNode::get(Store->getContext(),
2355 llvm::ConstantAsMetadata::get(
Builder.getInt32(1)));
2356 Store->setMetadata(llvm::LLVMContext::MD_nontemporal, Node);
2359 CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
2378 assert(LV.getType()->isConstantMatrixType());
2380 LV.setAddress(
Addr);
2396 llvm_unreachable(
"bad evaluation kind");
2459 if (
CGM.getCodeGenOpts().OptimizationLevel > 0) {
2461 llvm::MatrixBuilder MB(
Builder);
2462 MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened());
2464 llvm::LoadInst *Load =
2478 llvm::Type *RowTy = llvm::FixedVectorType::get(ElemTy, MT->
getNumColumns());
2479 llvm::Value *
Result = llvm::PoisonValue::get(RowTy);
2481 llvm::MatrixBuilder MB(
Builder);
2483 for (
unsigned Col = 0; Col < NumCols; ++Col) {
2484 llvm::Value *ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
2485 llvm::Value *EltIndex = MB.CreateIndex(Row, ColIdx, NumRows);
2486 llvm::Value *Elt =
Builder.CreateExtractElement(MatrixVec, EltIndex);
2487 llvm::Value *Lane = llvm::ConstantInt::get(
Builder.getInt32Ty(), Col);
2494 assert(LV.
isBitField() &&
"Unknown LValue type!");
2512 const unsigned StorageSize =
2515 assert(
static_cast<unsigned>(Offset + Info.
Size) <= StorageSize);
2516 unsigned HighBits = StorageSize - Offset - Info.
Size;
2518 Val =
Builder.CreateShl(Val, HighBits,
"bf.shl");
2519 if (Offset + HighBits)
2520 Val =
Builder.CreateAShr(Val, Offset + HighBits,
"bf.ashr");
2523 Val =
Builder.CreateLShr(Val, Offset,
"bf.lshr");
2524 if (
static_cast<unsigned>(Offset) + Info.
Size < StorageSize)
2526 Val, llvm::APInt::getLowBitsSet(StorageSize, Info.
Size),
"bf.clear");
2542 llvm::Type *DstTy = llvm::FixedVectorType::get(Vec->getType(), 1);
2543 llvm::Value *
Zero = llvm::Constant::getNullValue(
CGM.Int64Ty);
2544 Vec =
Builder.CreateInsertElement(DstTy, Vec,
Zero,
"cast.splat");
2554 llvm::Value *Elt = llvm::ConstantInt::get(
SizeTy, InIdx);
2556 llvm::Value *Element =
Builder.CreateExtractElement(Vec, Elt);
2559 if (Element->getType()->getPrimitiveSizeInBits() >
2560 LVTy->getPrimitiveSizeInBits())
2561 Element =
Builder.CreateTrunc(Element, LVTy);
2570 for (
unsigned i = 0; i != NumResultElts; ++i)
2573 Vec =
Builder.CreateShuffleVector(Vec, Mask);
2585 llvm::Type *VectorElementTy =
CGM.getTypes().ConvertType(EQT);
2593 Builder.CreateConstInBoundsGEP(CastToPointerElement, ix,
2596 return VectorBasePtrPlusIx;
2602 "Bad type for register variable");
2607 llvm::Type *OrigTy =
CGM.getTypes().ConvertType(LV.
getType());
2608 llvm::Type *Ty = OrigTy;
2609 if (OrigTy->isPointerTy())
2610 Ty =
CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
2611 llvm::Type *Types[] = { Ty };
2613 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
2615 F, llvm::MetadataAsValue::get(Ty->getContext(), RegName));
2616 if (OrigTy->isPointerTy())
2634 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2636 CGM.getDataLayout().getPrefTypeAlign(ElemTy));
2638 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2639 "vector element type must be at least byte-sized");
2642 if (Val->getType()->getPrimitiveSizeInBits() <
2643 ElemTy->getScalarSizeInBits())
2644 Val =
Builder.CreateZExt(Val, ElemTy->getScalarType());
2647 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2649 Builder.CreateGEP(DstAddr, {
Zero, Idx}, DestAddrTy, ElemAlign);
2657 llvm::Type *VecTy = Vec->getType();
2660 if (SrcVal->getType()->getPrimitiveSizeInBits() <
2661 VecTy->getScalarSizeInBits())
2662 SrcVal =
Builder.CreateZExt(SrcVal, VecTy->getScalarType());
2664 auto *IRStoreTy = dyn_cast<llvm::IntegerType>(Vec->getType());
2666 auto *IRVecTy = llvm::FixedVectorType::get(
2667 Builder.getInt1Ty(), IRStoreTy->getPrimitiveSizeInBits());
2668 Vec =
Builder.CreateBitCast(Vec, IRVecTy);
2675 if (
auto *EltTy = dyn_cast<llvm::FixedVectorType>(SrcVal->getType());
2676 EltTy && EltTy->getNumElements() == 1)
2677 SrcVal =
Builder.CreateBitCast(SrcVal, EltTy->getElementType());
2683 Vec =
Builder.CreateBitCast(Vec, IRStoreTy);
2702 if (
CGM.getCodeGenOpts().OptimizationLevel > 0) {
2704 llvm::MatrixBuilder MB(
Builder);
2705 MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened());
2710 llvm::Type *StorageElmTy = Load->getType()->getScalarType();
2711 InsertVal =
Builder.CreateZExt(InsertVal, StorageElmTy);
2714 Builder.CreateInsertElement(Load, InsertVal, Idx,
"matins");
2727 llvm::Value *MatrixVec =
2732 llvm::MatrixBuilder MB(
Builder);
2734 for (
unsigned Col = 0; Col < NumCols; ++Col) {
2735 llvm::Value *ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
2736 llvm::Value *EltIndex = MB.CreateIndex(Row, ColIdx, NumRows);
2737 llvm::Value *Lane = llvm::ConstantInt::get(
Builder.getInt32Ty(), Col);
2738 llvm::Value *NewElt =
Builder.CreateExtractElement(RowVal, Lane);
2739 MatrixVec =
Builder.CreateInsertElement(MatrixVec, NewElt, EltIndex);
2746 assert(Dst.
isBitField() &&
"Unknown LValue type");
2761 llvm_unreachable(
"present but none");
2796 CGM.getObjCRuntime().EmitObjCWeakAssign(*
this, src, LvalueDst);
2808 llvm::Value *RHS = dst.emitRawPointer(*
this);
2809 RHS =
Builder.CreatePtrToInt(RHS, ResultType,
"sub.ptr.rhs.cast");
2811 ResultType,
"sub.ptr.lhs.cast");
2812 llvm::Value *BytesBetween =
Builder.CreateSub(LHS, RHS,
"ivar.offset");
2813 CGM.getObjCRuntime().EmitObjCIvarAssign(*
this, src, dst, BytesBetween);
2815 CGM.getObjCRuntime().EmitObjCGlobalAssign(*
this, src, LvalueDst,
2819 CGM.getObjCRuntime().EmitObjCStrongCastAssign(*
this, src, LvalueDst);
2823 assert(Src.
isScalar() &&
"Can't emit an agg store with this method");
2839 llvm::Value *MaskedVal = SrcVal;
2841 const bool UseVolatile =
2844 const unsigned StorageSize =
2849 if (StorageSize != Info.
Size) {
2850 assert(StorageSize > Info.
Size &&
"Invalid bitfield size.");
2857 SrcVal, llvm::APInt::getLowBitsSet(StorageSize, Info.
Size),
2861 SrcVal =
Builder.CreateShl(SrcVal, Offset,
"bf.shl");
2865 Val, ~llvm::APInt::getBitsSet(StorageSize, Offset, Offset + Info.
Size),
2869 SrcVal =
Builder.CreateOr(Val, SrcVal,
"bf.set");
2871 assert(Offset == 0);
2878 CGM.getCodeGenOpts().ForceAAPCSBitfieldLoad)
2879 Builder.CreateLoad(Ptr,
true,
"bf.load");
2888 llvm::Value *ResultVal = MaskedVal;
2892 assert(Info.
Size <= StorageSize);
2893 unsigned HighBits = StorageSize - Info.
Size;
2895 ResultVal =
Builder.CreateShl(ResultVal, HighBits,
"bf.result.shl");
2896 ResultVal =
Builder.CreateAShr(ResultVal, HighBits,
"bf.result.ashr");
2912 SrcVal->getType()->getScalarSizeInBits())
2921 if (!DestAddrTy->isVectorTy()) {
2923 "this should only occur for non-vector l-values");
2936 CGM.getDataLayout().getPrefTypeAlign(DestAddrTy->getScalarType()));
2937 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2939 for (
unsigned I = 0; I != NumSrcElts; ++I) {
2940 llvm::Value *Val = VTy ?
Builder.CreateExtractElement(
2941 SrcVal, llvm::ConstantInt::get(
Int32Ty, I))
2948 DstElemAddr =
Builder.CreateGEP(
2949 DstAddr, {
Zero, llvm::ConstantInt::get(
Int32Ty, FieldNo)},
2950 DestAddrTy, ElemAlign);
2959 llvm::Type *VecTy = Vec->getType();
2962 unsigned NumSrcElts = VTy->getNumElements();
2964 if (NumDstElts == NumSrcElts) {
2969 for (
unsigned i = 0; i != NumSrcElts; ++i)
2972 Vec =
Builder.CreateShuffleVector(SrcVal, Mask);
2973 }
else if (NumDstElts > NumSrcElts) {
2979 for (
unsigned i = 0; i != NumSrcElts; ++i)
2980 ExtMask.push_back(i);
2981 ExtMask.resize(NumDstElts, -1);
2982 llvm::Value *ExtSrcVal =
Builder.CreateShuffleVector(SrcVal, ExtMask);
2985 for (
unsigned i = 0; i != NumDstElts; ++i)
2995 for (
unsigned i = 0; i != NumSrcElts; ++i)
2997 Vec =
Builder.CreateShuffleVector(Vec, ExtSrcVal, Mask);
3000 llvm_unreachable(
"unexpected shorten vector length");
3006 llvm::Value *Elt = llvm::ConstantInt::get(
SizeTy, InIdx);
3008 Vec =
Builder.CreateInsertElement(Vec, SrcVal, Elt);
3018 "Bad type for register variable");
3021 assert(RegName &&
"Register LValue is not metadata");
3024 llvm::Type *OrigTy =
CGM.getTypes().ConvertType(Dst.
getType());
3025 llvm::Type *Ty = OrigTy;
3026 if (OrigTy->isPointerTy())
3027 Ty =
CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
3028 llvm::Type *Types[] = { Ty };
3030 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
3032 if (OrigTy->isPointerTy())
3035 F, {llvm::MetadataAsValue::get(Ty->getContext(), RegName),
Value});
3043 bool IsMemberAccess=
false) {
3055 LV.setObjCIvar(
false);
3059 LV.setObjCIvar(
true);
3061 LV.setBaseIvarExp(Exp->getBase());
3066 if (
const auto *Exp = dyn_cast<DeclRefExpr>(E)) {
3067 if (
const auto *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
3068 if (VD->hasGlobalStorage()) {
3069 LV.setGlobalObjCRef(
true);
3077 if (
const auto *Exp = dyn_cast<UnaryOperator>(E)) {
3082 if (
const auto *Exp = dyn_cast<ParenExpr>(E)) {
3084 if (LV.isObjCIvar()) {
3091 LV.setObjCIvar(
false);
3096 if (
const auto *Exp = dyn_cast<GenericSelectionExpr>(E)) {
3101 if (
const auto *Exp = dyn_cast<ImplicitCastExpr>(E)) {
3106 if (
const auto *Exp = dyn_cast<CStyleCastExpr>(E)) {
3111 if (
const auto *Exp = dyn_cast<ObjCBridgedCastExpr>(E)) {
3116 if (
const auto *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
3118 if (LV.isObjCIvar() && !LV.isObjCArray())
3121 LV.setObjCIvar(
false);
3122 else if (LV.isGlobalObjCRef() && !LV.isObjCArray())
3125 LV.setGlobalObjCRef(
false);
3129 if (
const auto *Exp = dyn_cast<MemberExpr>(E)) {
3143 CGF, VD,
Addr, Loc);
3148 Addr =
Addr.withElementType(RealVarTy);
3154 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3155 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3159 if (!Res || ((*Res == OMPDeclareTargetDeclAttr::MT_To ||
3160 *Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
3163 assert(((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||
3164 ((*Res == OMPDeclareTargetDeclAttr::MT_To ||
3165 *Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
3167 "Expected link clause OR to clause with unified memory enabled.");
3177 llvm::LoadInst *Load =
3182 PTy, PointeeBaseInfo, PointeeTBAAInfo,
true);
3185 llvm::MDBuilder MDB(Ctx);
3187 if (
CGM.getTypes().getTargetAddressSpace(PTy) == 0 &&
3188 !
CGM.getCodeGenOpts().NullPointerIsValid)
3189 Load->setMetadata(llvm::LLVMContext::MD_nonnull,
3190 llvm::MDNode::get(Ctx, {}));
3196 llvm::LLVMContext::MD_align,
3197 llvm::MDNode::get(Ctx, MDB.createConstant(llvm::ConstantInt::get(
3198 Builder.getInt64Ty(), AlignVal))));
3203 true, PointeeBaseInfo,
3213 PointeeBaseInfo, PointeeTBAAInfo);
3223 BaseInfo, TBAAInfo);
3253 V = CGF.
Builder.CreateThreadLocalAddress(
V);
3261 VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
3276 if (FD->
hasAttr<WeakRefAttr>()) {
3291 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
V))
3292 V = llvm::NoCFIValue::get(GV);
3299 llvm::Value *ThisValue) {
3312 AsmLabelAttr *
Asm = VD->
getAttr<AsmLabelAttr>();
3313 assert(
Asm->getLabel().size() < 64-Name.size() &&
3314 "Register name too big");
3315 Name.append(
Asm->getLabel());
3316 llvm::NamedMDNode *M =
3317 CGM.
getModule().getOrInsertNamedMetadata(Name);
3318 if (M->getNumOperands() == 0) {
3321 llvm::Metadata *Ops[] = {Str};
3328 llvm::MetadataAsValue::get(CGM.
getLLVMContext(), M->getOperand(0));
3371 case llvm::GlobalValue::ExternalLinkage:
3372 case llvm::GlobalValue::LinkOnceODRLinkage:
3373 case llvm::GlobalValue::WeakODRLinkage:
3374 case llvm::GlobalValue::InternalLinkage:
3375 case llvm::GlobalValue::PrivateLinkage:
3387 "should not emit an unevaluated operand");
3389 if (
const auto *VD = dyn_cast<VarDecl>(ND)) {
3392 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
3400 (VD->getType()->isReferenceType() ||
3402 VD->getAnyInitializer(VD);
3404 E->
getLocation(), *VD->evaluateValue(), VD->getType());
3405 assert(Val &&
"failed to emit constant expression");
3408 if (!VD->getType()->isReferenceType()) {
3410 Addr =
CGM.createUnnamedGlobalFrom(*VD, Val,
3413 auto *PTy = llvm::PointerType::get(
3432 VD = VD->getCanonicalDecl();
3436 auto I = LocalDeclMap.find(VD);
3437 if (I != LocalDeclMap.end()) {
3439 if (VD->getType()->isReferenceType())
3447 CGM.getOpenMPRuntime().isNontemporalDecl(VD))
3464 CGM.getOpenMPRuntime().isNontemporalDecl(VD))
3480 "Should not use decl without marking it used!");
3482 if (ND->
hasAttr<WeakRefAttr>()) {
3488 if (
const auto *VD = dyn_cast<VarDecl>(ND)) {
3490 if (VD->hasLinkage() || VD->isStaticDataMember())
3496 auto iter = LocalDeclMap.find(VD);
3497 if (iter != LocalDeclMap.end()) {
3498 addr = iter->second;
3502 }
else if (VD->isStaticLocal()) {
3503 llvm::Constant *var =
CGM.getOrCreateStaticVarDecl(
3504 *VD,
CGM.getLLVMLinkageVarDefinition(VD));
3510 llvm_unreachable(
"DeclRefExpr for Decl not entered in LocalDeclMap?");
3521 VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
3528 bool isBlockByref = VD->isEscapingByref();
3534 LValue LV = VD->getType()->isReferenceType() ?
3538 bool isLocalStorage = VD->hasLocalStorage();
3540 bool NonGCable = isLocalStorage &&
3541 !VD->getType()->isReferenceType() &&
3548 bool isImpreciseLifetime =
3549 (isLocalStorage && !VD->hasAttr<ObjCPreciseLifetimeAttr>());
3550 if (isImpreciseLifetime)
3556 if (
const auto *FD = dyn_cast<FunctionDecl>(ND))
3562 if (
const auto *BD = dyn_cast<BindingDecl>(ND)) {
3579 if (
const auto *GD = dyn_cast<MSGuidDecl>(ND))
3583 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
3584 auto ATPO =
CGM.GetAddrOfTemplateParamObject(TPO);
3587 if (AS !=
T.getAddressSpace()) {
3589 auto PtrTy = llvm::PointerType::get(
CGM.getLLVMContext(), TargetAS);
3592 ATPO =
ConstantAddress(ASC, ATPO.getElementType(), ATPO.getAlignment());
3598 llvm_unreachable(
"Unhandled DeclRefExpr");
3608 default: llvm_unreachable(
"Unknown unary operator lvalue!");
3611 assert(!
T.isNull() &&
"CodeGenFunction::EmitUnaryOpLValue: Illegal type");
3633 assert(LV.
isSimple() &&
"real/imag on non-ordinary l-value");
3650 CGM.getTBAAInfoForSubobject(LV,
T));
3657 bool isInc = E->
getOpcode() == UO_PreInc;
3680 assert(SL !=
nullptr &&
"No StringLiteral name in PredefinedExpr");
3681 StringRef FnName =
CurFn->getName();
3682 FnName.consume_front(
"\01");
3683 StringRef NameItems[] = {
3685 std::string GVName = llvm::join(NameItems, NameItems + 2,
".");
3686 if (
auto *BD = dyn_cast_or_null<BlockDecl>(
CurCodeDecl)) {
3687 std::string Name = std::string(SL->getString());
3688 if (!Name.empty()) {
3689 unsigned Discriminator =
3690 CGM.getCXXABI().getMangleContext().getBlockId(BD,
true);
3692 Name +=
"_" + Twine(Discriminator + 1).str();
3693 auto C =
CGM.GetAddrOfConstantCString(Name, GVName);
3696 auto C =
CGM.GetAddrOfConstantCString(std::string(FnName), GVName);
3700 auto C =
CGM.GetAddrOfConstantStringFromLiteral(SL, GVName);
3717 if (llvm::Constant *
C =
CGM.getTypeDescriptorFromMap(
T))
3722 bool IsBitInt =
false;
3724 if (
T->isIntegerType()) {
3727 (
T->isSignedIntegerType() ? 1 : 0);
3731 if (
T->isSignedIntegerType() &&
T->getAs<
BitIntType>()) {
3734 " non positive amount of bits in __BitInt type");
3736 " too many bits in __BitInt type");
3743 }
else if (
T->isFloatingType()) {
3752 (
intptr_t)
T.getAsOpaquePtr(), StringRef(),
3753 StringRef(), {}, Buffer, {});
3758 char S[6] = {
'\0',
'\0',
'\0',
'\0',
'\0',
'\0'};
3761 llvm::support::endian::write32(S + 1, Bits,
3763 ? llvm::endianness::big
3764 : llvm::endianness::little);
3765 StringRef Str = StringRef(S,
sizeof(S) /
sizeof(
decltype(S[0])));
3769 llvm::Constant *Components[] = {
3773 llvm::Constant *Descriptor = llvm::ConstantStruct::getAnon(Components);
3775 auto *GV =
new llvm::GlobalVariable(
3776 CGM.getModule(), Descriptor->getType(),
3777 true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
3778 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3779 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(GV);
3782 CGM.setTypeDescriptorInMap(
T, GV);
3790 if (
V->getType() == TargetTy)
3795 if (
V->getType()->isFloatingPointTy()) {
3796 unsigned Bits =
V->getType()->getPrimitiveSizeInBits().getFixedValue();
3797 if (Bits <= TargetTy->getIntegerBitWidth())
3803 if (
V->getType()->isIntegerTy() &&
3804 V->getType()->getIntegerBitWidth() <= TargetTy->getIntegerBitWidth())
3805 return Builder.CreateZExt(
V, TargetTy);
3808 if (!
V->getType()->isPointerTy()) {
3813 return Builder.CreatePtrToInt(
V, TargetTy);
3826 llvm::Constant *Filename;
3833 int PathComponentsToStrip =
3834 CGM.getCodeGenOpts().EmitCheckPathComponentsToStrip;
3835 if (PathComponentsToStrip < 0) {
3836 assert(PathComponentsToStrip !=
INT_MIN);
3837 int PathComponentsToKeep = -PathComponentsToStrip;
3838 auto I = llvm::sys::path::rbegin(FilenameString);
3839 auto E = llvm::sys::path::rend(FilenameString);
3840 while (I != E && --PathComponentsToKeep)
3843 FilenameString = FilenameString.substr(I - E);
3844 }
else if (PathComponentsToStrip > 0) {
3845 auto I = llvm::sys::path::begin(FilenameString);
3846 auto E = llvm::sys::path::end(FilenameString);
3847 while (I != E && PathComponentsToStrip--)
3852 FilenameString.substr(I - llvm::sys::path::begin(FilenameString));
3854 FilenameString = llvm::sys::path::filename(FilenameString);
3858 CGM.GetAddrOfConstantCString(std::string(FilenameString),
".src");
3859 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(
3861 FilenameGV.getPointer()->stripPointerCasts()));
3862 Filename = FilenameGV.getPointer();
3866 Filename = llvm::Constant::getNullValue(
Int8PtrTy);
3873 return llvm::ConstantStruct::getAnon(
Data);
3878enum class CheckRecoverableKind {
3889static CheckRecoverableKind
3891 if (Ordinal == SanitizerKind::SO_Vptr)
3892 return CheckRecoverableKind::AlwaysRecoverable;
3893 else if (Ordinal == SanitizerKind::SO_Return ||
3894 Ordinal == SanitizerKind::SO_Unreachable)
3895 return CheckRecoverableKind::Unrecoverable;
3897 return CheckRecoverableKind::Recoverable;
3901struct SanitizerHandlerInfo {
3902 char const *
const Name;
3908#define SANITIZER_CHECK(Enum, Name, Version, Msg) {#Name, Version},
3910#undef SANITIZER_CHECK
3914 llvm::FunctionType *FnType,
3917 CheckRecoverableKind RecoverKind,
bool IsFatal,
3918 llvm::BasicBlock *ContBB,
bool NoMerge) {
3919 assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
3920 std::optional<ApplyDebugLocation> DL;
3921 if (!CGF.
Builder.getCurrentDebugLocation()) {
3925 bool NeedsAbortSuffix =
3926 IsFatal && RecoverKind != CheckRecoverableKind::Unrecoverable;
3928 bool HandlerPreserveAllRegs =
3931 const StringRef CheckName = CheckInfo.Name;
3932 std::string FnName =
"__ubsan_handle_" + CheckName.str();
3933 if (CheckInfo.Version && !MinimalRuntime)
3934 FnName +=
"_v" + llvm::utostr(CheckInfo.Version);
3936 FnName +=
"_minimal";
3937 if (NeedsAbortSuffix)
3939 if (HandlerPreserveAllRegs && !NeedsAbortSuffix)
3940 FnName +=
"_preserve";
3942 !IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable;
3946 B.addAttribute(llvm::Attribute::NoReturn)
3947 .addAttribute(llvm::Attribute::NoUnwind);
3949 B.addUWTableAttr(llvm::UWTableKind::Default);
3954 llvm::AttributeList::FunctionIndex, B),
3960 HandlerCall->addFnAttr(llvm::Attribute::NoMerge);
3961 if (HandlerPreserveAllRegs && !NeedsAbortSuffix) {
3963 HandlerCall->setCallingConv(llvm::CallingConv::PreserveAll);
3966 HandlerCall->setDoesNotReturn();
3967 CGF.
Builder.CreateUnreachable();
3974 ArrayRef<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Checked,
3978 assert(Checked.size() > 0);
3979 assert(CheckHandler >= 0 &&
3983 llvm::Value *FatalCond =
nullptr;
3984 llvm::Value *RecoverableCond =
nullptr;
3985 llvm::Value *TrapCond =
nullptr;
3986 bool NoMerge =
false;
3993 for (
auto &[Check, Ord] : Checked) {
3994 llvm::Value *GuardedCheck = Check;
3996 (
CGM.getCodeGenOpts().SanitizeSkipHotCutoffs[Ord] > 0)) {
3998 CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check),
3999 llvm::ConstantInt::get(
CGM.Int8Ty, Ord));
4004 llvm::Value *&
Cond =
CGM.getCodeGenOpts().SanitizeTrap.has(Ord) ? TrapCond
4005 :
CGM.getCodeGenOpts().SanitizeRecover.has(Ord)
4010 if (!
CGM.getCodeGenOpts().SanitizeMergeHandlers.has(Ord))
4016 if (!FatalCond && !RecoverableCond)
4019 llvm::Value *JointCond;
4020 if (FatalCond && RecoverableCond)
4021 JointCond =
Builder.CreateAnd(FatalCond, RecoverableCond);
4023 JointCond = FatalCond ? FatalCond : RecoverableCond;
4027 assert(
SanOpts.has(Checked[0].second));
4029 for (
int i = 1, n = Checked.size(); i < n; ++i) {
4031 "All recoverable kinds in a single check must be same!");
4032 assert(
SanOpts.has(Checked[i].second));
4038 llvm::Instruction *Branch =
Builder.CreateCondBr(JointCond, Cont, Handlers);
4041 llvm::MDNode *Node = MDHelper.createLikelyBranchWeights();
4042 Branch->setMetadata(llvm::LLVMContext::MD_prof, Node);
4046 if (
CGM.getCodeGenOpts().SanitizeMinimalRuntime) {
4057 Args.reserve(DynamicArgs.size() + 1);
4058 ArgTypes.reserve(DynamicArgs.size() + 1);
4061 if (!StaticArgs.empty()) {
4062 llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
4063 auto *InfoPtr =
new llvm::GlobalVariable(
4064 CGM.getModule(), Info->getType(),
4067 false, llvm::GlobalVariable::PrivateLinkage, Info,
"",
4068 nullptr, llvm::GlobalVariable::NotThreadLocal,
4069 CGM.getDataLayout().getDefaultGlobalsAddressSpace());
4070 InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4071 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
4072 Args.push_back(InfoPtr);
4073 ArgTypes.push_back(Args.back()->getType());
4076 for (llvm::Value *DynamicArg : DynamicArgs) {
4081 llvm::FunctionType *FnType =
4082 llvm::FunctionType::get(
CGM.VoidTy, ArgTypes,
false);
4084 if (!FatalCond || !RecoverableCond) {
4088 (FatalCond !=
nullptr), Cont, NoMerge);
4092 llvm::BasicBlock *NonFatalHandlerBB =
4095 Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
4098 NonFatalHandlerBB, NoMerge);
4109 llvm::ConstantInt *TypeId, llvm::Value *Ptr,
4114 llvm::BranchInst *BI =
Builder.CreateCondBr(
Cond, Cont, CheckBB);
4117 llvm::MDNode *Node = MDHelper.createLikelyBranchWeights();
4118 BI->setMetadata(llvm::LLVMContext::MD_prof, Node);
4122 bool WithDiag = !
CGM.getCodeGenOpts().SanitizeTrap.has(Ordinal);
4124 llvm::CallInst *CheckCall;
4125 llvm::FunctionCallee SlowPathFn;
4127 llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
4129 new llvm::GlobalVariable(
CGM.getModule(), Info->getType(),
false,
4130 llvm::GlobalVariable::PrivateLinkage, Info);
4131 InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4132 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
4134 SlowPathFn =
CGM.getModule().getOrInsertFunction(
4135 "__cfi_slowpath_diag",
4138 CheckCall =
Builder.CreateCall(SlowPathFn, {TypeId, Ptr, InfoPtr});
4140 SlowPathFn =
CGM.getModule().getOrInsertFunction(
4143 CheckCall =
Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
4148 CheckCall->setDoesNotThrow();
4156 llvm::Module *M = &
CGM.getModule();
4158 QualType QInt64Ty =
C.getIntTypeForBitwidth(64,
false);
4165 FnArgs.push_back(&ArgCallsiteTypeId);
4166 FnArgs.push_back(&ArgAddr);
4167 FnArgs.push_back(&ArgCFICheckFailData);
4169 CGM.getTypes().arrangeBuiltinFunctionDeclaration(
C.VoidTy,
FnArgs);
4171 llvm::Function *F = llvm::Function::Create(
4173 llvm::GlobalValue::WeakAnyLinkage,
"__cfi_check", M);
4175 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
4176 F->setAlignment(llvm::Align(4096));
4179 llvm::LLVMContext &Ctx = M->getContext();
4180 llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx,
"entry", F);
4183 llvm::CallInst::Create(M->getFunction(
"__cfi_check_fail"), Args,
"", BB);
4184 llvm::ReturnInst::Create(Ctx,
nullptr, BB);
4195 auto CheckHandler = SanitizerHandler::CFICheckFail;
4202 {SanitizerKind::SO_CFIVCall, SanitizerKind::SO_CFINVCall,
4203 SanitizerKind::SO_CFIDerivedCast, SanitizerKind::SO_CFIUnrelatedCast,
4204 SanitizerKind::SO_CFIICall},
4211 Args.push_back(&ArgData);
4212 Args.push_back(&ArgAddr);
4217 llvm::Function *F = llvm::Function::Create(
4219 llvm::GlobalValue::WeakODRLinkage,
"__cfi_check_fail", &
CGM.getModule());
4222 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
4223 F->setVisibility(llvm::GlobalValue::HiddenVisibility);
4243 llvm::Value *DataIsNotNullPtr =
4248 EmitTrapCheck(DataIsNotNullPtr, SanitizerHandler::CFICheckFail,
4251 llvm::StructType *SourceLocationTy =
4253 llvm::StructType *CfiCheckFailDataTy =
4256 llvm::Value *
V =
Builder.CreateConstGEP2_32(
4260 llvm::Value *CheckKind =
Builder.CreateLoad(CheckKindAddr);
4262 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
4263 CGM.getLLVMContext(),
4264 llvm::MDString::get(
CGM.getLLVMContext(),
"all-vtables"));
4265 llvm::Value *ValidVtable =
Builder.CreateZExt(
4266 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::type_test),
4267 {Addr, AllVtables}),
4270 const std::pair<int, SanitizerKind::SanitizerOrdinal> CheckKinds[] = {
4277 for (
auto CheckKindOrdinalPair : CheckKinds) {
4278 int Kind = CheckKindOrdinalPair.first;
4285 Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(
Int8Ty, Kind));
4286 if (
CGM.getLangOpts().Sanitize.has(Ordinal))
4287 EmitCheck(std::make_pair(
Cond, Ordinal), SanitizerHandler::CFICheckFail,
4300 CGM.addUsedGlobal(F);
4304 if (
SanOpts.has(SanitizerKind::Unreachable)) {
4305 auto CheckOrdinal = SanitizerKind::SO_Unreachable;
4306 auto CheckHandler = SanitizerHandler::BuiltinUnreachable;
4322 if ((
int)TrapBBs.size() <= CheckHandlerID)
4323 TrapBBs.resize(CheckHandlerID + 1);
4325 llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
4327 llvm::DILocation *TrapLocation =
Builder.getCurrentDebugLocation();
4328 llvm::StringRef TrapMessage;
4329 llvm::StringRef TrapCategory;
4330 auto DebugTrapReasonKind =
CGM.getCodeGenOpts().getSanitizeDebugTrapReasons();
4332 DebugTrapReasonKind ==
4338 TrapCategory =
"Undefined Behavior Sanitizer";
4342 DebugTrapReasonKind !=
4346 TrapLocation, TrapCategory, TrapMessage);
4349 NoMerge = NoMerge || !
CGM.getCodeGenOpts().OptimizationLevel ||
4353 if (TrapBB && !NoMerge) {
4354 auto Call = TrapBB->begin();
4357 Call->applyMergedLocation(
Call->getDebugLoc(), TrapLocation);
4359 Builder.CreateCondBr(Checked, Cont, TrapBB,
4360 MDHelper.createLikelyBranchWeights());
4363 Builder.CreateCondBr(Checked, Cont, TrapBB,
4364 MDHelper.createLikelyBranchWeights());
4369 llvm::CallInst *TrapCall =
4370 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
4371 llvm::ConstantInt::get(
CGM.Int8Ty, CheckHandlerID));
4373 if (!
CGM.getCodeGenOpts().TrapFuncName.empty()) {
4374 auto A = llvm::Attribute::get(
getLLVMContext(),
"trap-func-name",
4375 CGM.getCodeGenOpts().TrapFuncName);
4376 TrapCall->addFnAttr(A);
4379 TrapCall->addFnAttr(llvm::Attribute::NoMerge);
4380 TrapCall->setDoesNotReturn();
4381 TrapCall->setDoesNotThrow();
4389 llvm::CallInst *TrapCall =
4390 Builder.CreateCall(
CGM.getIntrinsic(IntrID));
4392 if (!
CGM.getCodeGenOpts().TrapFuncName.empty()) {
4393 auto A = llvm::Attribute::get(
getLLVMContext(),
"trap-func-name",
4394 CGM.getCodeGenOpts().TrapFuncName);
4395 TrapCall->addFnAttr(A);
4399 TrapCall->addFnAttr(llvm::Attribute::NoMerge);
4407 "Array to pointer decay must have array source type!");
4416 Addr =
Addr.withElementType(NewTy);
4422 "Expected pointer to array");
4433 if (TBAAInfo) *TBAAInfo =
CGM.getTBAAAccessInfo(EltType);
4442 const auto *CE = dyn_cast<CastExpr>(E);
4443 if (!CE || CE->getCastKind() != CK_ArrayToPointerDecay)
4455 llvm::Type *elemType,
4461 const llvm::Twine &name =
"arrayidx") {
4473 llvm::Type *elementType,
bool inbounds,
4476 const llvm::Twine &name =
"arrayidx") {
4496 return D && D->
hasAttr<BPFPreserveStaticOffsetAttr>();
4503 if (PointeeType.
isNull())
4516 llvm::Function *Fn =
4518 llvm::CallInst *
Call = CGF.
Builder.CreateCall(Fn, {
Addr.emitRawPointer(CGF)});
4536 if (
const auto *ME = dyn_cast<MemberExpr>(E))
4537 return ME->getMemberDecl()->hasAttr<BPFPreserveAccessIndexAttr>();
4539 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
4540 const auto *VarDef = dyn_cast<VarDecl>(DRE->getDecl());
4544 const auto *PtrT = VarDef->getType()->getAs<
PointerType>();
4550 if (
const auto *RecT = dyn_cast<RecordType>(PointeeT))
4551 return RecT->getDecl()
4552 ->getMostRecentDecl()
4553 ->
hasAttr<BPFPreserveAccessIndexAttr>();
4566 const llvm::Twine &name =
"arrayidx") {
4569 for (
auto *idx : indices.drop_back())
4588 llvm::Value *eltPtr;
4589 auto LastIndex = dyn_cast<llvm::ConstantInt>(indices.back());
4594 signedIndices, loc, eltAlign, name);
4598 unsigned idx = LastIndex->getZExtValue();
4599 llvm::DIType *DbgInfo =
nullptr;
4602 eltPtr = CGF.
Builder.CreatePreserveArrayAccessIndex(
4614struct StructFieldAccess
4615 :
public ConstStmtVisitor<StructFieldAccess, const Expr *> {
4616 const Expr *VisitCastExpr(
const CastExpr *E) {
4621 const Expr *VisitParenExpr(
const ParenExpr *E) {
4630 const FieldDecl *Field, int64_t &Offset) {
4633 unsigned FieldNo = 0;
4668 if (FD1OuterRec != FD2OuterRec)
4670 return std::optional<int64_t>();
4672 int64_t FD1Offset = 0;
4674 return std::optional<int64_t>();
4676 int64_t FD2Offset = 0;
4678 return std::optional<int64_t>();
4680 return std::make_optional<int64_t>(FD1Offset - FD2Offset);
4692 QualType IndexType, llvm::Value *IndexVal,
bool Accessed,
4693 bool FlexibleArray) {
4694 const auto *ME = dyn_cast<MemberExpr>(ArrayExpr->
IgnoreImpCasts());
4695 if (!ME || !ME->getMemberDecl()->getType()->isCountAttributedType())
4700 if (FlexibleArray &&
4701 !ME->isFlexibleArrayMemberLike(
getContext(), StrictFlexArraysLevel))
4709 if (std::optional<int64_t> Diff =
4724 ArrayInst =
Builder.CreatePointerBitCastOrAddrSpaceCast(ArrayInst,
4728 llvm::Value *BoundsVal =
4730 Builder.getInt32(*Diff),
".counted_by.gep");
4732 ".counted_by.load");
4736 CountFD->
getType(), Accessed);
4744 llvm::Value *IdxPre =
4746 bool SignedIndices =
false;
4747 auto EmitIdxAfterBase = [&, IdxPre](
bool Promote) -> llvm::Value * {
4750 assert(E->
getRHS() == E->
getIdx() &&
"index was neither LHS nor RHS");
4756 SignedIndices |= IdxSigned;
4758 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4762 if (Promote && Idx->getType() !=
IntPtrTy)
4775 auto *Idx = EmitIdxAfterBase(
false);
4776 assert(LHS.
isSimple() &&
"Can only subscript lvalue vectors here!");
4784 std::optional<LValue> LV;
4787 LV =
CGM.getHLSLRuntime().emitResourceArraySubscriptExpr(E, *
this);
4789 LV =
CGM.getHLSLRuntime().emitBufferArraySubscriptExpr(E, *
this,
4801 auto *Idx = EmitIdxAfterBase(
true);
4808 CGM.getTBAAInfoForSubobject(LV, EltType));
4820 auto *Idx = EmitIdxAfterBase(
true);
4830 Idx =
Builder.CreateMul(Idx, numElements);
4832 Idx =
Builder.CreateNSWMul(Idx, numElements);
4844 auto *Idx = EmitIdxAfterBase(
true);
4847 llvm::Value *InterfaceSizeVal =
4848 llvm::ConstantInt::get(Idx->getType(), InterfaceSize.
getQuantity());
4850 llvm::Value *ScaledIdx =
Builder.CreateMul(Idx, InterfaceSizeVal);
4856 llvm::Type *OrigBaseElemTy =
Addr.getElementType();
4861 llvm::Value *EltPtr =
4863 ScaledIdx,
false, SignedIndices, E->
getExprLoc());
4870 assert(Array->getType()->isArrayType() &&
4871 "Array to pointer decay must have array source type!");
4875 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
4879 auto *Idx = EmitIdxAfterBase(
true);
4881 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4889 *
this, ArrayLV.
getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
4893 if (!
CGM.getCodeGenOpts().NewStructPathTBAA) {
4896 EltTBAAInfo =
CGM.getTBAAInfoForSubobject(ArrayLV, E->
getType());
4901 EltTBAAInfo =
CGM.getTBAAAccessInfo(E->
getType());
4923 auto *Idx = EmitIdxAfterBase(
true);
4930 if (
SanOpts.has(SanitizerKind::ArrayBounds)) {
4931 StructFieldAccess Visitor;
4934 if (
const auto *CE = dyn_cast_if_present<CastExpr>(
Base);
4935 CE && CE->getCastKind() == CK_LValueToRValue)
4965 if (
auto *RowConst = llvm::dyn_cast<llvm::ConstantInt>(RowIdx)) {
4970 Indices.reserve(NumCols);
4972 unsigned Row = RowConst->getZExtValue();
4973 unsigned Start = Row * NumCols;
4974 for (
unsigned C = 0;
C < NumCols; ++
C)
4975 Indices.push_back(llvm::ConstantInt::get(
Int32Ty, Start +
C));
4977 llvm::Constant *Elts = llvm::ConstantVector::get(Indices);
4991 "incomplete matrix subscript expressions should be rejected during Sema");
4998 llvm::Value *NumRows =
Builder.getIntN(
4999 RowIdx->getType()->getScalarSizeInBits(),
5001 llvm::Value *FinalIdx =
5012 bool IsLowerBound) {
5014 if (
auto *ASE = dyn_cast<ArraySectionExpr>(
Base->IgnoreParenImpCasts())) {
5018 BaseInfo = BaseLVal.getBaseInfo();
5023 Addr =
Addr.withElementType(NewTy);
5029 "Expected pointer to array");
5039 BaseInfo.mergeForCast(TypeBaseInfo);
5048 bool IsLowerBound) {
5051 "OpenACC Array section codegen not implemented");
5055 if (
auto *AT =
getContext().getAsArrayType(BaseTy))
5056 ResultExprTy = AT->getElementType();
5059 llvm::Value *Idx =
nullptr;
5067 LowerBound->getType()->hasSignedIntegerRepresentation());
5069 Idx = llvm::ConstantInt::getNullValue(
IntPtrTy);
5074 auto &
C =
CGM.getContext();
5076 llvm::APSInt ConstLength;
5079 if (std::optional<llvm::APSInt>
CL = Length->getIntegerConstantExpr(
C)) {
5086 if (std::optional<llvm::APSInt> LB =
5087 LowerBound->getIntegerConstantExpr(
C)) {
5089 LowerBound =
nullptr;
5094 else if (!LowerBound)
5097 if (Length || LowerBound) {
5098 auto *LowerBoundVal =
5102 LowerBound->getType()->hasSignedIntegerRepresentation())
5103 : llvm::ConstantInt::get(
IntPtrTy, ConstLowerBound);
5108 Length->getType()->hasSignedIntegerRepresentation())
5109 : llvm::ConstantInt::get(
IntPtrTy, ConstLength);
5110 Idx =
Builder.CreateAdd(LowerBoundVal, LengthVal,
"lb_add_len",
5113 if (Length && LowerBound) {
5115 Idx, llvm::ConstantInt::get(
IntPtrTy, 1),
"idx_sub_1",
5119 Idx = llvm::ConstantInt::get(
IntPtrTy, ConstLength + ConstLowerBound);
5125 if (
auto *VAT =
C.getAsVariableArrayType(ArrayTy)) {
5126 Length = VAT->getSizeExpr();
5127 if (std::optional<llvm::APSInt> L = Length->getIntegerConstantExpr(
C)) {
5132 auto *CAT =
C.getAsConstantArrayType(ArrayTy);
5133 assert(CAT &&
"unexpected type for array initializer");
5134 ConstLength = CAT->getSize();
5137 auto *LengthVal =
Builder.CreateIntCast(
5139 Length->getType()->hasSignedIntegerRepresentation());
5141 LengthVal, llvm::ConstantInt::get(
IntPtrTy, 1),
"len_sub_1",
5146 Idx = llvm::ConstantInt::get(
IntPtrTy, ConstLength);
5155 if (
auto *VLA =
getContext().getAsVariableArrayType(ResultExprTy)) {
5161 BaseTy, VLA->getElementType(), IsLowerBound);
5170 Idx =
Builder.CreateMul(Idx, NumElements);
5172 Idx =
Builder.CreateNSWMul(Idx, NumElements);
5181 assert(Array->getType()->isArrayType() &&
5182 "Array to pointer decay must have array source type!");
5186 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
5193 *
this, ArrayLV.
getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
5194 ResultExprTy, !
getLangOpts().PointerOverflowDefined,
5197 TBAAInfo =
CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
5201 ResultExprTy, IsLowerBound);
5224 Base.getQuals().removeObjCGCAttr();
5233 "Result must be a vector");
5241 if (LTy->getScalarSizeInBits() > Vec->getType()->getScalarSizeInBits())
5242 Vec =
Builder.CreateZExt(Vec, LTy);
5243 Builder.CreateStore(Vec, VecMem);
5254 if (
Base.isSimple()) {
5255 llvm::Constant *CV =
5260 if (
Base.isMatrixRow())
5263 assert(
Base.isExtVectorElt() &&
"Can only subscript lvalue vec elts here!");
5265 llvm::Constant *BaseElts =
Base.getExtVectorElts();
5268 for (
unsigned Index : Indices)
5269 CElts.push_back(BaseElts->getAggregateElement(Index));
5270 llvm::Constant *CV = llvm::ConstantVector::get(CElts);
5277 while (
auto *BaseMemberExpr = dyn_cast<MemberExpr>(UnderlyingBaseExpr))
5278 UnderlyingBaseExpr = BaseMemberExpr->getBase()->
IgnoreParens();
5290 return CGM.getHLSLRuntime().emitBufferMemberExpr(*
this, E);
5297 bool IsInBounds = !
getLangOpts().PointerOverflowDefined &&
5309 SkippedChecks.
set(SanitizerKind::Alignment,
true);
5311 SkippedChecks.
set(SanitizerKind::Null,
true);
5319 if (
auto *Field = dyn_cast<FieldDecl>(ND)) {
5327 CGM.getOpenMPRuntime().isNontemporalDecl(Field)) ||
5334 if (
const auto *FD = dyn_cast<FunctionDecl>(ND))
5337 llvm_unreachable(
"Unhandled member declaration!");
5344 llvm::Value *ThisValue) {
5345 bool HasExplicitObjectParameter =
false;
5346 const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
CurCodeDecl);
5348 HasExplicitObjectParameter = MD->isExplicitObjectMemberFunction();
5349 assert(MD->getParent()->isLambda());
5350 assert(MD->getParent() == Field->getParent());
5353 if (HasExplicitObjectParameter) {
5355 auto It = LocalDeclMap.find(D);
5356 assert(It != LocalDeclMap.end() &&
"explicit parameter not loaded?");
5357 Address AddrOfExplicitObject = It->getSecond();
5368 if (ThisTy != LambdaTy) {
5371 LambdaLV.
getAddress(), ThisTy, BasePathArray.begin(),
5391 unsigned FieldIndex) {
5392 unsigned I = 0, Skipped = 0;
5395 if (I == FieldIndex)
5397 if (F->isUnnamedBitField())
5402 return FieldIndex - Skipped;
5412 if (Offset.isZero())
5425 const FieldDecl *field,
bool IsInBounds) {
5458 if (RD->isDynamicClass())
5461 for (
const auto &
Base : RD->bases())
5465 for (
const FieldDecl *Field : RD->fields())
5480 const bool UseVolatile =
isAAPCS(
CGM.getTarget()) &&
5481 CGM.getCodeGenOpts().AAPCSBitfieldWidth &&
5512 llvm::Type *FieldIntTy = llvm::Type::getIntNTy(
getLLVMContext(), SS);
5513 Addr =
Addr.withElementType(FieldIntTy);
5548 assert(!FieldTBAAInfo.
Offset &&
5549 "Nonzero offset for an access with no base type!");
5562 FieldTBAAInfo.
Size =
5569 if (
auto *ClassDef = dyn_cast<CXXRecordDecl>(rec)) {
5570 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
5571 ClassDef->isDynamicClass()) {
5585 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
5589 addr =
Builder.CreateLaunderInvariantGroup(addr);
5632 if (field->
hasAttr<AnnotateAttr>())
5648 QualType FieldType = Field->getType();
5654 *
this,
Base.getAddress(), Field,
5659 V =
V.withElementType(llvmType);
5668 CGM.getTBAAInfoForSubobject(
Base, FieldType));
5704 assert(E->
isTransparent() &&
"non-transparent glvalue init list");
5712 const Expr *Operand) {
5713 if (
auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Operand->IgnoreParens())) {
5715 return std::nullopt;
5724std::optional<LValue> HandleConditionalOperatorLValueSimpleCase(
5726 const Expr *condExpr = E->
getCond();
5731 std::swap(Live, Dead);
5740 if (
auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Live->
IgnoreParens())) {
5751 return std::nullopt;
5753struct ConditionalInfo {
5754 llvm::BasicBlock *lhsBlock, *rhsBlock;
5755 std::optional<LValue> LHS, RHS;
5760template<
typename FuncTy>
5762 const AbstractConditionalOperator *E,
5763 const FuncTy &BranchGenFunc) {
5779 Info.lhsBlock = CGF.
Builder.GetInsertBlock();
5782 CGF.
Builder.CreateBr(endBlock);
5789 Info.rhsBlock = CGF.
Builder.GetInsertBlock();
5801 "Unexpected conditional operator!");
5806 if (HandleConditionalOperatorLValueSimpleCase(*
this, E))
5809 EmitConditionalBlocks(*
this, E, [](CodeGenFunction &CGF,
const Expr *E) {
5816 if (!
expr->isGLValue()) {
5819 "Unexpected conditional operator!");
5824 if (std::optional<LValue> Res =
5825 HandleConditionalOperatorLValueSimpleCase(*
this,
expr))
5828 ConditionalInfo Info = EmitConditionalBlocks(
5829 *
this,
expr, [](CodeGenFunction &CGF,
const Expr *E) {
5833 if ((Info.LHS && !Info.LHS->isSimple()) ||
5834 (Info.RHS && !Info.RHS->isSimple()))
5837 if (Info.LHS && Info.RHS) {
5838 Address lhsAddr = Info.LHS->getAddress();
5839 Address rhsAddr = Info.RHS->getAddress();
5841 lhsAddr, rhsAddr, Info.lhsBlock, Info.rhsBlock,
5844 std::max(Info.LHS->getBaseInfo().getAlignmentSource(),
5845 Info.RHS->getBaseInfo().getAlignmentSource());
5847 Info.LHS->getTBAAInfo(), Info.RHS->getTBAAInfo());
5851 assert((Info.LHS || Info.RHS) &&
5852 "both operands of glvalue conditional are throw-expressions?");
5853 return Info.LHS ? *Info.LHS : *Info.RHS;
5865 auto RestoreCurCast =
5866 llvm::make_scope_exit([
this, Prev =
CurCast] {
CurCast = Prev; });
5871 case CK_LValueToRValueBitCast:
5872 case CK_ArrayToPointerDecay:
5873 case CK_FunctionToPointerDecay:
5874 case CK_NullToMemberPointer:
5875 case CK_NullToPointer:
5876 case CK_IntegralToPointer:
5877 case CK_PointerToIntegral:
5878 case CK_PointerToBoolean:
5879 case CK_IntegralCast:
5880 case CK_BooleanToSignedIntegral:
5881 case CK_IntegralToBoolean:
5882 case CK_IntegralToFloating:
5883 case CK_FloatingToIntegral:
5884 case CK_FloatingToBoolean:
5885 case CK_FloatingCast:
5886 case CK_FloatingRealToComplex:
5887 case CK_FloatingComplexToReal:
5888 case CK_FloatingComplexToBoolean:
5889 case CK_FloatingComplexCast:
5890 case CK_FloatingComplexToIntegralComplex:
5891 case CK_IntegralRealToComplex:
5892 case CK_IntegralComplexToReal:
5893 case CK_IntegralComplexToBoolean:
5894 case CK_IntegralComplexCast:
5895 case CK_IntegralComplexToFloatingComplex:
5896 case CK_DerivedToBaseMemberPointer:
5897 case CK_BaseToDerivedMemberPointer:
5898 case CK_MemberPointerToBoolean:
5899 case CK_ReinterpretMemberPointer:
5900 case CK_AnyPointerToBlockPointerCast:
5901 case CK_ARCProduceObject:
5902 case CK_ARCConsumeObject:
5903 case CK_ARCReclaimReturnedObject:
5904 case CK_ARCExtendBlockObject:
5905 case CK_CopyAndAutoreleaseBlockObject:
5906 case CK_IntToOCLSampler:
5907 case CK_FloatingToFixedPoint:
5908 case CK_FixedPointToFloating:
5909 case CK_FixedPointCast:
5910 case CK_FixedPointToBoolean:
5911 case CK_FixedPointToIntegral:
5912 case CK_IntegralToFixedPoint:
5914 case CK_HLSLVectorTruncation:
5915 case CK_HLSLMatrixTruncation:
5916 case CK_HLSLArrayRValue:
5917 case CK_HLSLElementwiseCast:
5918 case CK_HLSLAggregateSplatCast:
5922 llvm_unreachable(
"dependent cast kind in IR gen!");
5924 case CK_BuiltinFnToFnPtr:
5925 llvm_unreachable(
"builtin functions are handled elsewhere");
5928 case CK_NonAtomicToAtomic:
5929 case CK_AtomicToNonAtomic:
5939 case CK_ConstructorConversion:
5940 case CK_UserDefinedConversion:
5941 case CK_CPointerToObjCPointerCast:
5942 case CK_BlockPointerToObjCPointerCast:
5943 case CK_LValueToRValue:
5958 if (
V.getElementType() !=
T)
5965 case CK_UncheckedDerivedToBase:
5966 case CK_DerivedToBase: {
5980 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
5984 case CK_BaseToDerived: {
5999 if (
SanOpts.has(SanitizerKind::CFIDerivedCast))
6005 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6007 case CK_LValueBitCast: {
6011 CGM.EmitExplicitCastExprType(CE,
this);
6016 if (
SanOpts.has(SanitizerKind::CFIUnrelatedCast))
6022 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6024 case CK_AddressSpaceConversion: {
6034 case CK_ObjCObjectLValueCast: {
6038 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6040 case CK_ZeroToOCLOpaqueType:
6041 llvm_unreachable(
"NULL to OpenCL opaque type lvalue cast is not valid");
6043 case CK_VectorSplat: {
6051 llvm_unreachable(
"Unhandled lvalue cast kind?");
6059std::pair<LValue, LValue>
6074 return std::make_pair(BaseLV, TempLV);
6082 llvm::Value *
Addr = TempLV.getAddress().getBasePointer();
6087 Address TmpAddr(
Addr, ElTy, TempLV.getAlignment());
6097 llvm::DenseMap<const OpaqueValueExpr*,LValue>::iterator
6098 it = OpaqueLValues.find(e);
6100 if (it != OpaqueLValues.end())
6103 assert(e->
isUnique() &&
"LValue for a nonunique OVE hasn't been emitted");
6111 llvm::DenseMap<const OpaqueValueExpr*,RValue>::iterator
6112 it = OpaqueRValues.find(e);
6114 if (it != OpaqueRValues.end())
6117 assert(e->
isUnique() &&
"RValue for a nonunique OVE hasn't been emitted");
6123 return OpaqueLValues.contains(E);
6124 return OpaqueRValues.contains(E);
6148 llvm_unreachable(
"bad evaluation kind");
6157 llvm::CallBase **CallOrInvoke) {
6158 llvm::CallBase *CallOrInvokeStorage;
6159 if (!CallOrInvoke) {
6160 CallOrInvoke = &CallOrInvokeStorage;
6163 auto AddCoroElideSafeOnExit = llvm::make_scope_exit([&] {
6165 auto *I = *CallOrInvoke;
6167 I->addFnAttr(llvm::Attribute::CoroElideSafe);
6175 if (
const auto *CE = dyn_cast<CXXMemberCallExpr>(E))
6178 if (
const auto *CE = dyn_cast<CUDAKernelCallExpr>(E))
6183 if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(E))
6184 if (
const auto *MD =
6185 dyn_cast_if_present<CXXMethodDecl>(CE->getCalleeDecl());
6186 MD && MD->isImplicitObjectMemberFunction())
6201 nullptr, CallOrInvoke);
6207 llvm::CallBase **CallOrInvoke) {
6210 nullptr, CallOrInvoke);
6218 if (!PD->isInlineBuiltinDeclaration())
6227 std::string NoBuiltinFD = (
"no-builtin-" + FD->
getName()).str();
6228 std::string NoBuiltins =
"no-builtins";
6231 std::string FDInlineName = (Ident +
".inline").str();
6233 bool IsPredefinedLibFunction =
6235 bool HasAttributeNoBuiltin =
6236 CGF.
CurFn->getAttributes().hasFnAttr(NoBuiltinFD) ||
6237 CGF.
CurFn->getAttributes().hasFnAttr(NoBuiltins);
6241 if (CGF.
CurFn->getName() != FDInlineName &&
6244 llvm::Function *Fn = llvm::cast<llvm::Function>(CalleePtr);
6245 llvm::Module *M = Fn->getParent();
6246 llvm::Function *Clone = M->getFunction(FDInlineName);
6248 Clone = llvm::Function::Create(Fn->getFunctionType(),
6249 llvm::GlobalValue::InternalLinkage,
6250 Fn->getAddressSpace(), FDInlineName, M);
6251 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
6262 else if (!IsPredefinedLibFunction || !HasAttributeNoBuiltin)
6268 FD->
hasAttr<CUDAGlobalAttr>())
6276 if (DeviceKernelAttr::isOpenCLSpelling(FD->
getAttr<DeviceKernelAttr>()))
6285 if (
auto ICE = dyn_cast<ImplicitCastExpr>(E)) {
6286 if (ICE->getCastKind() == CK_FunctionToPointerDecay ||
6287 ICE->getCastKind() == CK_BuiltinFnToFnPtr) {
6293 if (ICE->getCastKind() == CK_LValueToRValue) {
6294 const Expr *SubExpr = ICE->getSubExpr();
6296 std::pair<llvm::Value *, CGPointerAuthInfo>
Result =
6303 if (
const auto *VD =
6314 }
else if (
auto DRE = dyn_cast<DeclRefExpr>(E)) {
6315 if (
auto FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
6318 }
else if (
auto ME = dyn_cast<MemberExpr>(E)) {
6319 if (
auto FD = dyn_cast<FunctionDecl>(ME->getMemberDecl())) {
6325 }
else if (
auto NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
6329 }
else if (
auto PDE = dyn_cast<CXXPseudoDestructorExpr>(E)) {
6334 llvm::Value *calleePtr;
6346 if (
const auto *VD =
6352 CGCallee callee(calleeInfo, calleePtr, pointerAuth);
6368 assert(E->
getOpcode() == BO_Assign &&
"unexpected binary l-value");
6431 llvm::Value *
Result =
nullptr;
6434 if (
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
6449 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*
this,
6466 llvm_unreachable(
"bad evaluation kind");
6478 if (
CGM.getHLSLRuntime().emitResourceArrayCopy(LHS, E->
getRHS(), *
this))
6489 llvm::CallBase **CallOrInvoke) {
6497 "Can't have a scalar return unless the return type is a "
6510 &&
"binding l-value to type which needs a temporary");
6548 "Can't have a scalar return unless the return type is a "
6562 return CGM.getObjCRuntime().EmitIvarOffset(*
this,
Interface, Ivar);
6570 return Builder.CreateZExtOrTrunc(OffsetValue,
6575 llvm::Value *BaseValue,
6577 unsigned CVRQualifiers) {
6578 return CGM.getObjCRuntime().EmitObjCValueForIvar(*
this, ObjectTy, BaseValue,
6579 Ivar, CVRQualifiers);
6584 llvm::Value *BaseValue =
nullptr;
6595 ObjectTy = BaseExpr->
getType();
6617 llvm::CallBase **CallOrInvoke,
6622 "Call must have function pointer type!");
6624 const Decl *TargetDecl =
6627 assert((!isa_and_present<FunctionDecl>(TargetDecl) ||
6629 "trying to emit a call to an immediate function");
6637 if (
SanOpts.has(SanitizerKind::Function) &&
6640 if (llvm::Constant *PrefixSig =
6641 CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(
CGM)) {
6642 auto CheckOrdinal = SanitizerKind::SO_Function;
6643 auto CheckHandler = SanitizerHandler::FunctionTypeMismatch;
6647 llvm::Type *PrefixSigType = PrefixSig->getType();
6648 llvm::StructType *PrefixStructTy = llvm::StructType::get(
6649 CGM.getLLVMContext(), {PrefixSigType, Int32Ty},
true);
6651 llvm::Value *CalleePtr = Callee.getFunctionPointer();
6652 if (
CGM.getCodeGenOpts().PointerAuth.FunctionPointers) {
6655 Address(CalleePtr, CalleePtr->getType(),
6657 CalleePtr->getPointerAlignment(
CGM.getDataLayout())),
6658 Callee.getPointerAuthInfo(),
nullptr);
6659 CalleePtr =
Addr.emitRawPointer(*
this);
6671 llvm::Value *AlignedCalleePtr;
6672 if (
CGM.getTriple().isARM() ||
CGM.getTriple().isThumb()) {
6673 llvm::Value *CalleeAddress =
6675 llvm::Value *Mask = llvm::ConstantInt::getSigned(
IntPtrTy, ~1);
6676 llvm::Value *AlignedCalleeAddress =
6677 Builder.CreateAnd(CalleeAddress, Mask);
6679 Builder.CreateIntToPtr(AlignedCalleeAddress, CalleePtr->getType());
6681 AlignedCalleePtr = CalleePtr;
6684 llvm::Value *CalleePrefixStruct = AlignedCalleePtr;
6685 llvm::Value *CalleeSigPtr =
6686 Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 0);
6687 llvm::Value *CalleeSig =
6689 llvm::Value *CalleeSigMatch =
Builder.CreateICmpEQ(CalleeSig, PrefixSig);
6693 Builder.CreateCondBr(CalleeSigMatch, TypeCheck, Cont);
6696 llvm::Value *CalleeTypeHash =
Builder.CreateAlignedLoad(
6698 Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 1),
6700 llvm::Value *CalleeTypeHashMatch =
6701 Builder.CreateICmpEQ(CalleeTypeHash, TypeHash);
6704 EmitCheck(std::make_pair(CalleeTypeHashMatch, CheckOrdinal), CheckHandler,
6705 StaticData, {CalleePtr});
6714 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
6715 FD && DeviceKernelAttr::isOpenCLSpelling(FD->getAttr<DeviceKernelAttr>()))
6716 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FnType);
6722 if (
SanOpts.has(SanitizerKind::CFIICall) &&
6724 auto CheckOrdinal = SanitizerKind::SO_CFIICall;
6725 auto CheckHandler = SanitizerHandler::CFICheckFail;
6729 llvm::Metadata *MD =
6730 CGM.CreateMetadataIdentifierForFnType(
QualType(FnType, 0));
6732 llvm::Value *TypeId = llvm::MetadataAsValue::get(
getLLVMContext(), MD);
6734 llvm::Value *CalleePtr = Callee.getFunctionPointer();
6735 llvm::Value *TypeTest =
Builder.CreateCall(
6736 CGM.getIntrinsic(llvm::Intrinsic::type_test), {CalleePtr, TypeId});
6738 auto CrossDsoTypeId =
CGM.CreateCrossDsoCfiTypeId(MD);
6739 llvm::Constant *StaticData[] = {
6744 if (
CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
6748 EmitCheck(std::make_pair(TypeTest, CheckOrdinal), CheckHandler,
6749 StaticData, {CalleePtr, llvm::UndefValue::get(
IntPtrTy)});
6764 bool StaticOperator =
false;
6765 if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
6766 if (OCE->isAssignmentOp())
6769 switch (OCE->getOperator()) {
6771 case OO_GreaterGreater:
6783 if (
const auto *MD =
6784 dyn_cast_if_present<CXXMethodDecl>(OCE->getCalleeDecl());
6785 MD && MD->isStatic())
6786 StaticOperator =
true;
6790 if (StaticOperator) {
6794 Arguments = drop_begin(Arguments, 1);
6796 EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), Arguments,
6800 Args, FnType, Chain);
6803 *ResolvedFnInfo = &FnInfo;
6808 if (
CGM.getLangOpts().HIP && !
CGM.getLangOpts().CUDAIsDevice &&
6811 llvm::Value *Handle = Callee.getFunctionPointer();
6813 Address(Handle, Handle->getType(),
CGM.getPointerAlign()));
6814 Callee.setFunctionPointer(
Stub);
6816 llvm::CallBase *LocalCallOrInvoke =
nullptr;
6820 if (
auto *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
6821 if (CalleeDecl->hasAttr<RestrictAttr>() ||
6822 CalleeDecl->hasAttr<MallocSpanAttr>() ||
6823 CalleeDecl->hasAttr<AllocSizeAttr>()) {
6825 if (
SanOpts.has(SanitizerKind::AllocToken)) {
6832 *CallOrInvoke = LocalCallOrInvoke;
6851 bool IsInBounds = !
getLangOpts().PointerOverflowDefined &&
6854 E, BaseAddr, OffsetV, MPT, IsInBounds, &BaseInfo, &TBAAInfo);
6856 return MakeAddrLValue(MemberAddr, MPT->getPointeeType(), BaseInfo, TBAAInfo);
6873 llvm_unreachable(
"bad evaluation kind");
6877 assert(Val->getType()->isFPOrFPVectorTy());
6882 llvm::MDNode *Node = MDHelper.createFPMath(Accuracy);
6888 llvm::Type *EltTy = Val->getType()->getScalarType();
6889 if (!EltTy->isFloatTy())
6893 !
CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) ||
6895 !
CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) {
6909 llvm::Type *EltTy = Val->getType()->getScalarType();
6910 if (!EltTy->isFloatTy())
6914 !
CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) ||
6916 !
CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) {
6930 struct LValueOrRValue {
6944 LValueOrRValue result;
6948 const Expr *semantic = *i;
6952 if (
const auto *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
6954 if (ov->isUnique()) {
6955 assert(ov != resultExpr &&
6956 "A unique OVE cannot be used as the result expression");
6964 if (ov == resultExpr && ov->
isPRValue() && !forLValue &&
6969 opaqueData = OVMA::bind(CGF, ov, LV);
6974 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
6977 if (ov == resultExpr) {
6985 opaques.push_back(opaqueData);
6989 }
else if (semantic == resultExpr) {
7021 std::tuple<LValue, QualType, llvm::SmallVector<llvm::Value *, 4>>, 16>
7023 llvm::IntegerType *IdxTy = llvm::IntegerType::get(
getLLVMContext(), 32);
7024 WorkList.push_back({Val, Val.
getType(), {llvm::ConstantInt::get(IdxTy, 0)}});
7026 while (!WorkList.empty()) {
7027 auto [LVal,
T, IdxList] = WorkList.pop_back_val();
7028 T =
T.getCanonicalType().getUnqualifiedType();
7031 if (
const auto *CAT = dyn_cast<ConstantArrayType>(
T)) {
7032 uint64_t Size = CAT->getZExtSize();
7033 for (int64_t I = Size - 1; I > -1; I--) {
7035 IdxListCopy.push_back(llvm::ConstantInt::get(IdxTy, I));
7036 WorkList.emplace_back(LVal, CAT->getElementType(), IdxListCopy);
7038 }
else if (
const auto *RT = dyn_cast<RecordType>(
T)) {
7040 assert(!
Record->isUnion() &&
"Union types not supported in flat cast.");
7045 std::tuple<LValue, QualType, llvm::SmallVector<llvm::Value *, 4>>, 16>
7054 "HLSL doesn't support multiple inheritance.");
7057 IdxListCopy.push_back(llvm::ConstantInt::get(
7059 ReverseList.emplace_back(LVal,
Base->getType(), IdxListCopy);
7068 bool createdGEP =
false;
7069 for (
auto *FD :
Record->fields()) {
7070 if (FD->isBitField()) {
7071 if (FD->isUnnamedBitField())
7075 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList,
7076 LLVMT, Align,
"gep");
7080 ReverseList.push_back({FieldLVal, FD->
getType(), {}});
7083 IdxListCopy.push_back(
7085 ReverseList.emplace_back(LVal, FD->getType(), IdxListCopy);
7089 std::reverse(ReverseList.begin(), ReverseList.end());
7090 llvm::append_range(WorkList, ReverseList);
7091 }
else if (
const auto *VT = dyn_cast<VectorType>(
T)) {
7094 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList, LLVMT,
7095 Align,
"vector.gep");
7097 for (
unsigned I = 0, E = VT->getNumElements(); I < E; I++) {
7098 llvm::Constant *Idx = llvm::ConstantInt::get(IdxTy, I);
7102 AccessList.emplace_back(LV);
7105 if (!IdxList.empty()) {
7108 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList,
7109 LLVMT, Align,
"gep");
7112 AccessList.emplace_back(LVal);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static void setObjCGCLValueClass(const ASTContext &Ctx, const Expr *E, LValue &LV, bool IsMemberAccess=false)
static LValue EmitGlobalNamedRegister(const VarDecl *VD, CodeGenModule &CGM)
Named Registers are named metadata pointing to the register name which will be read from/written to a...
static llvm::Value * emitHashMix(CGBuilderTy &Builder, llvm::Value *Acc, llvm::Value *Ptr)
static const Expr * isSimpleArrayDecayOperand(const Expr *E)
isSimpleArrayDecayOperand - If the specified expr is a simple decay from an array to pointer,...
static bool getFieldOffsetInBits(CodeGenFunction &CGF, const RecordDecl *RD, const FieldDecl *Field, int64_t &Offset)
The offset of a field from the beginning of the record.
static bool hasBPFPreserveStaticOffset(const RecordDecl *D)
ConstantEmissionKind
Can we constant-emit a load of a reference to a variable of the given type?
static bool isConstantEmittableObjectType(QualType type)
Given an object of the given canonical type, can we safely copy a value out of it based on its initia...
static LValue EmitCapturedFieldLValue(CodeGenFunction &CGF, const FieldDecl *FD, llvm::Value *ThisValue)
static std::optional< LValue > EmitLValueOrThrowExpression(CodeGenFunction &CGF, const Expr *Operand)
Emit the operand of a glvalue conditional operator.
static CheckRecoverableKind getRecoverableKind(SanitizerKind::SanitizerOrdinal Ordinal)
static llvm::Value * emitArraySubscriptGEP(CodeGenFunction &CGF, llvm::Type *elemType, llvm::Value *ptr, ArrayRef< llvm::Value * > indices, bool inbounds, bool signedIndices, SourceLocation loc, const llvm::Twine &name="arrayidx")
SmallVector< llvm::Value *, 8 > RecIndicesTy
static GlobalDecl getGlobalDeclForDirectCall(const FunctionDecl *FD)
static LValue EmitFunctionDeclLValue(CodeGenFunction &CGF, const Expr *E, GlobalDecl GD)
static RawAddress MaybeConvertMatrixAddress(RawAddress Addr, CodeGenFunction &CGF, bool IsVector=true)
static LValueOrRValue emitPseudoObjectExpr(CodeGenFunction &CGF, const PseudoObjectExpr *E, bool forLValue, AggValueSlot slot)
static Address wrapWithBPFPreserveStaticOffset(CodeGenFunction &CGF, Address &Addr)
static llvm::StringRef GetUBSanTrapForHandler(SanitizerHandler ID)
static llvm::Value * getArrayIndexingBound(CodeGenFunction &CGF, const Expr *Base, QualType &IndexedType, LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel)
If Base is known to point to the start of an array, return the length of that array.
static RValue EmitLoadOfMatrixLValue(LValue LV, SourceLocation Loc, CodeGenFunction &CGF)
static ConstantEmissionKind checkVarTypeForConstantEmission(QualType type)
static Address emitAddrOfZeroSizeField(CodeGenFunction &CGF, Address Base, const FieldDecl *Field, bool IsInBounds)
Get the address of a zero-sized field within a record.
static QualType getConstantExprReferredType(const FullExpr *E, const ASTContext &Ctx)
static Address emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base, const FieldDecl *field, bool IsInBounds)
Drill down to the storage of a field without walking into reference types.
static bool getRangeForType(CodeGenFunction &CGF, QualType Ty, llvm::APInt &Min, llvm::APInt &End, bool StrictEnums, bool IsBool)
static std::optional< int64_t > getOffsetDifferenceInBits(CodeGenFunction &CGF, const FieldDecl *FD1, const FieldDecl *FD2)
Returns the relative offset difference between FD1 and FD2.
static CGCallee EmitDirectCallee(CodeGenFunction &CGF, GlobalDecl GD)
static LValue EmitThreadPrivateVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType T, Address Addr, llvm::Type *RealVarTy, SourceLocation Loc)
static bool getGEPIndicesToField(CodeGenFunction &CGF, const RecordDecl *RD, const FieldDecl *Field, RecIndicesTy &Indices)
static bool OnlyHasInlineBuiltinDeclaration(const FunctionDecl *FD)
static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, const Expr *E, const VarDecl *VD)
static bool hasAnyVptr(const QualType Type, const ASTContext &Context)
static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase)
Given an array base, check whether its member access belongs to a record with preserve_access_index a...
static Address emitDeclTargetVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType T)
VariableTypeDescriptorKind
@ TK_Float
A floating-point type.
@ TK_Unknown
Any other type. The value representation is unspecified.
@ TK_Integer
An integer type.
@ TK_BitInt
An _BitInt(N) type.
static void EmitStoreOfMatrixScalar(llvm::Value *value, LValue lvalue, bool isInit, CodeGenFunction &CGF)
static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo, KnownNonNull_t IsKnownNonNull, CodeGenFunction &CGF)
static Address emitPreserveStructAccess(CodeGenFunction &CGF, LValue base, Address addr, const FieldDecl *field)
const SanitizerHandlerInfo SanitizerHandlers[]
static void emitCheckHandlerCall(CodeGenFunction &CGF, llvm::FunctionType *FnType, ArrayRef< llvm::Value * > FnArgs, SanitizerHandler CheckHandler, CheckRecoverableKind RecoverKind, bool IsFatal, llvm::BasicBlock *ContBB, bool NoMerge)
static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, LValueBaseInfo &BaseInfo, TBAAAccessInfo &TBAAInfo, QualType BaseTy, QualType ElTy, bool IsLowerBound)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static Address createReferenceTemporary(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *inner)
static bool isAAPCS(const TargetInfo &targetInfo)
Helper method to check if the underlying ABI is AAPCS.
static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx, CharUnits eltSize)
static void pushTemporaryCleanup(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *e, Address referenceTemporary)
static QualType getFixedSizeElementType(const ASTContext &astContext, const VariableArrayType *vla)
static bool canEmitSpuriousReferenceToVariable(CIRGenFunction &cgf, const DeclRefExpr *e, const VarDecl *vd)
Determine whether we can emit a reference to vd from the current context, despite not necessarily hav...
static DeclRefExpr * tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf, const MemberExpr *me)
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Record Record
Defines the clang::Module class, which describes a module in the source code.
static const SanitizerMask AlwaysRecoverable
static const SanitizerMask Unrecoverable
#define LIST_SANITIZER_CHECKS
Defines the SourceManager interface.
static QualType getPointeeType(const MemRegion *R)
a trap message and trap category.
const LValueBase getLValueBase() const
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
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.
Builtin::Context & BuiltinInfo
const LangOptions & getLangOpts() const
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
llvm::DenseMap< const CXXMethodDecl *, CXXCastPath > LambdaCastPaths
For capturing lambdas with an explicit object parameter whose type is derived from the lambda type,...
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
CanQualType getCanonicalTagType(const TagDecl *TD) const
unsigned getTargetAddressSpace(LangAS AS) const
bool isSentinelNullExpr(const Expr *E)
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/...
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Expr * getBase()
Get base of the array section.
Expr * getLength()
Get length of array section.
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getLowerBound()
Get lower bound of array section.
bool isOpenACCArraySection() const
SourceLocation getColonLocFirst() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
SourceLocation getExprLoc() const LLVM_READONLY
Expr * getLHS()
An array access can be written A[4] or 4[A] (both are equivalent).
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
A builtin binary operation expression such as "x + y" or "x <= y".
SourceLocation getExprLoc() const
static bool isAdditiveOp(Opcode Opc)
A fixed int type of a specified bitwidth.
unsigned getNumBits() const
bool isPredefinedLibFunction(unsigned ID) const
Determines whether this builtin is a predefined libc/libm function, such as "malloc",...
Represents binding an expression to a temporary.
CXXTemporary * getTemporary()
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
Represents a C++ destructor within a class.
Represents a C++ struct/union/class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
bool isDynamicClass() const
bool hasDefinition() const
const CXXRecordDecl * getStandardLayoutBaseWithFields() const
If this is a standard-layout class or union, any and all data members will be declared in the same ty...
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCoroElideSafe() const
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
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?
llvm::MaybeAlign getAsMaybeAlign() const
getAsMaybeAlign - Returns Quantity as a valid llvm::Align or std::nullopt, Beware llvm::MaybeAlign as...
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
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 fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
@ None
Trap Messages are omitted.
@ Detailed
Trap Message includes more context (e.g.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * getBasePointer() const
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 withPointer(llvm::Value *NewPointer, KnownNonNull_t IsKnownNonNull) const
Return address with different pointer, but same element type and alignment.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
Address withAlignment(CharUnits NewAlignment) const
Return address with different alignment, but same pointer and element type.
llvm::PointerType * getType() const
Return the type of the pointer value.
static AggValueSlot ignored()
ignored - Returns an aggregate value slot indicating that the aggregate value is being ignored.
Address getAddress() const
void setExternallyDestructed(bool destructed=true)
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.
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 ...
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
Address CreateConstInBoundsByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Given a pointer to i8, adjust it by a given constant offset.
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Address CreateConstGEP2_32(Address Addr, unsigned Idx0, unsigned Idx1, const llvm::Twine &Name="")
Address CreateConstArrayGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = [n x T]* ... produce name = getelementptr inbounds addr, i64 0, i64 index where i64 is a...
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Address CreateConstByteGEP(Address Addr, CharUnits Offset, const llvm::Twine &Name="")
Address CreatePreserveStructAccessIndex(Address Addr, unsigned Index, unsigned FieldIndex, llvm::MDNode *DbgInfo)
Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")
virtual llvm::Function * getKernelStub(llvm::GlobalValue *Handle)=0
Get kernel stub by kernel handle.
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType)=0
Emit a reference to a non-local thread_local variable (including triggering the initialization of all...
virtual bool usesThreadWrapperFunction(const VarDecl *VD) const =0
Abstract information about a function or function prototype.
const GlobalDecl getCalleeDecl() const
All available information about a concrete callee.
CGCalleeInfo getAbstractInfo() const
const CXXPseudoDestructorExpr * getPseudoDestructorExpr() const
bool isPseudoDestructor() const
static CGCallee forBuiltin(unsigned builtinID, const FunctionDecl *builtinDecl)
unsigned getBuiltinID() const
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
const FunctionDecl * getBuiltinDecl() const
static CGCallee forPseudoDestructor(const CXXPseudoDestructorExpr *E)
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)
Emit standalone debug info for a type.
llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
CGFunctionInfo - Class to encapsulate the information about a function definition.
virtual Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, SourceLocation Loc)
Returns address of the threadprivate variable for the current thread.
virtual ConstantAddress getAddrOfDeclareTargetVar(const VarDecl *VD)
Returns the address of the variable marked as declare target with link clause OR as declare target wi...
bool hasRequiresUnifiedSharedMemory() const
Return whether the unified_shared_memory has been specified.
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.
unsigned getLLVMFieldNo(const FieldDecl *FD) const
Return llvm::StructType element number that corresponds to the field FD.
bool containsFieldDecl(const FieldDecl *FD) const
CallArgList - Type for representing both the value and type of arguments in a call.
void addWriteback(LValue srcLV, Address temporary, llvm::Value *toUse, const Expr *writebackExpr=nullptr)
void add(RValue rvalue, QualType type)
The scope of a CXXDefaultInitExpr.
An object to manage conditionally-evaluated expressions.
llvm::BasicBlock * getStartingBlock() const
Returns a block which will be executed prior to each evaluation of the conditional code.
static ConstantEmission forValue(llvm::Constant *C)
static ConstantEmission forReference(llvm::Constant *C)
LValue getReferenceLValue(CodeGenFunction &CGF, const Expr *RefExpr) const
llvm::Constant * getValue() const
A non-RAII class containing all the information about a bound opaque value.
static bool shouldBindAsLValue(const Expr *expr)
static OpaqueValueMappingData bind(CodeGenFunction &CGF, const OpaqueValueExpr *ov, const Expr *e)
An RAII object to set (and then clear) a mapping for an OpaqueValueExpr.
static bool shouldBindAsLValue(const Expr *expr)
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
RAII object to set/unset CodeGenFunction::IsSanitizerScope.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
LValue EmitMatrixSubscriptExpr(const MatrixSubscriptExpr *E)
LValue EmitCoawaitLValue(const CoawaitExpr *E)
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.
llvm::Value * EmitObjCConsumeObject(QualType T, llvm::Value *Ptr)
Produce the code for a CK_ARCConsumeObject.
void EmitBoundsCheckImpl(const Expr *ArrayExpr, QualType ArrayBaseType, llvm::Value *IndexVal, QualType IndexType, llvm::Value *BoundsVal, QualType BoundsType, bool Accessed)
LValue EmitLoadOfReferenceLValue(LValue RefLVal)
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
RValue EmitObjCMessageExpr(const ObjCMessageExpr *E, ReturnValueSlot Return=ReturnValueSlot())
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
void EmitCXXConstructExpr(const CXXConstructExpr *E, AggValueSlot Dest)
LValue EmitCXXConstructLValue(const CXXConstructExpr *E)
LValue EmitConditionalOperatorLValue(const AbstractConditionalOperator *E)
std::pair< LValue, llvm::Value * > EmitARCStoreAutoreleasing(const BinaryOperator *e)
ComplexPairTy EmitComplexPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
void SetDivFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
SanitizerSet SanOpts
Sanitizers enabled for this function.
LValue EmitInitListLValue(const InitListExpr *E)
bool isUnderlyingBasePointerConstantNull(const Expr *E)
Check whether the underlying base pointer is a constant null.
void EmitARCInitWeak(Address addr, llvm::Value *value)
i8* @objc_initWeak(i8** addr, i8* value) Returns value.
RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
LValue EmitArraySubscriptExpr(const ArraySubscriptExpr *E, bool Accessed=false)
Address LoadCXXThisAddress()
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
LValue EmitObjCMessageExprLValue(const ObjCMessageExpr *E)
llvm::Value * GetCountedByFieldExprGEP(const Expr *Base, const FieldDecl *FD, const FieldDecl *CountDecl)
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
const CastExpr * CurCast
If a cast expression is being visited, this holds the current cast's expression.
llvm::Type * ConvertType(QualType T)
Address EmitCXXUuidofExpr(const CXXUuidofExpr *E)
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)
static Destroyer destroyARCWeak
CGCapturedStmtInfo * CapturedStmtInfo
RValue EmitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E)
ComplexPairTy EmitLoadOfComplex(LValue src, SourceLocation loc)
EmitLoadOfComplex - Load a complex number from the specified l-value.
bool inSuspendBlock() const
llvm::Value * EmitARCRetain(QualType type, llvm::Value *value)
Produce the code to do a retain.
llvm::Value * EmitPointerAuthQualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType ValueType, Address StorageAddress, bool IsKnownNonNull)
CleanupKind getARCCleanupKind()
Retrieves the default cleanup kind for an ARC cleanup.
void EmitAggFinalDestCopy(QualType Type, AggValueSlot Dest, const LValue &Src, ExprValueKind SrcKind)
EmitAggFinalDestCopy - Emit copy of the specified aggregate into destination address.
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 EmitStoreThroughExtVectorComponentLValue(RValue Src, LValue Dst)
RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
LValue EmitCompoundLiteralLValue(const CompoundLiteralExpr *E)
RValue convertTempToRValue(Address addr, QualType type, SourceLocation Loc)
Given the address of a temporary variable, produce an r-value of its type.
LValue EmitObjCIsaExpr(const ObjCIsaExpr *E)
void EmitStoreThroughBitfieldLValue(RValue Src, LValue Dst, llvm::Value **Result=nullptr)
EmitStoreThroughBitfieldLValue - Store Src into Dst with same constraints as EmitStoreThroughLValue.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
LValue EmitCXXUuidofLValue(const CXXUuidofExpr *E)
llvm::Value * EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV, bool isInc, bool isPre)
void SetSqrtFPAccuracy(llvm::Value *Val)
Set the minimum required accuracy of the given sqrt operation based on CodeGenOpts.
RValue EmitSimpleCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke=nullptr)
Emit a CallExpr without considering whether it might be a subclass.
static bool isNullPointerAllowed(TypeCheckKind TCK)
Determine whether the pointer type check TCK permits null pointers.
RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e, AggValueSlot slot=AggValueSlot::ignored())
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.
unsigned getDebugInfoFIndex(const RecordDecl *Rec, unsigned FieldIndex)
Get the record field index as represented in debug info.
const LangOptions & getLangOpts() const
void EmitCfiCheckFail()
Emit a cross-DSO CFI failure handling function.
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
llvm::Value * EmitARCStoreStrong(LValue lvalue, llvm::Value *value, bool resultIgnored)
Store into a strong object.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
LValue EmitPointerToDataMemberBinaryExpr(const BinaryOperator *E)
LValue EmitLValueForIvar(QualType ObjectTy, llvm::Value *Base, const ObjCIvarDecl *Ivar, unsigned CVRQualifiers)
Address GetAddressOfDerivedClass(Address Value, const CXXRecordDecl *Derived, CastExpr::path_const_iterator PathBegin, CastExpr::path_const_iterator PathEnd, bool NullCheckValue)
void EmitIgnoredConditionalOperator(const AbstractConditionalOperator *E)
void EmitCountedByBoundsChecking(const Expr *ArrayExpr, QualType ArrayType, Address ArrayInst, QualType IndexType, llvm::Value *IndexVal, bool Accessed, bool FlexibleArray)
EmitCountedByBoundsChecking - If the array being accessed has a "counted_by" attribute,...
Address EmitFieldAnnotations(const FieldDecl *D, Address V)
Emit field annotations for the given field & value.
void pushDestroy(QualType::DestructionKind dtorKind, Address addr, QualType type)
pushDestroy - Push the standard destructor for the given type as at least a normal cleanup.
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc)
Given an assignment *LHS = RHS, emit a test that checks if RHS is nonnull, if LHS is marked _Nonnull.
llvm::Value * EmitPointerAuthUnqualify(PointerAuthQualifier Qualifier, llvm::Value *Pointer, QualType PointerType, Address StorageAddress, bool IsKnownNonNull)
void EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init)
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
Address EmitLoadOfPointer(Address Ptr, const PointerType *PtrTy, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
Load a pointer with type PtrTy stored at address Ptr.
RValue EmitLoadOfGlobalRegLValue(LValue LV)
Load of global named registers are always calls to intrinsics.
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.
TypeCheckKind
Situations in which we might emit a check for the suitability of a pointer or glvalue.
@ TCK_DowncastPointer
Checking the operand of a static_cast to a derived pointer type.
@ TCK_DowncastReference
Checking the operand of a static_cast to a derived reference type.
@ TCK_MemberAccess
Checking the object expression in a non-static data member access.
@ TCK_Store
Checking the destination of a store. Must be suitably sized and aligned.
@ TCK_UpcastToVirtualBase
Checking the operand of a cast to a virtual base object.
@ TCK_MemberCall
Checking the 'this' pointer for a call to a non-static member function.
@ TCK_DynamicOperation
Checking the operand of a dynamic_cast or a typeid expression.
@ TCK_ReferenceBinding
Checking the bound value in a reference binding.
@ TCK_Upcast
Checking the operand of a cast to a base object.
LValue EmitBinaryOperatorLValue(const BinaryOperator *E)
bool InNoMergeAttributedStmt
True if the current statement has nomerge attribute.
LValue EmitComplexCompoundAssignmentLValue(const CompoundAssignOperator *E)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
void maybeAttachRangeForLoad(llvm::LoadInst *Load, QualType Ty, SourceLocation Loc)
void EmitBitfieldConversionCheck(llvm::Value *Src, QualType SrcType, llvm::Value *Dst, QualType DstType, const CGBitFieldInfo &Info, SourceLocation Loc)
Emit a check that an [implicit] conversion of a bitfield.
LValue EmitPseudoObjectLValue(const PseudoObjectExpr *e)
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
LValue EmitOpaqueValueLValue(const OpaqueValueExpr *e)
llvm::Value * LoadPassedObjectSize(const Expr *E, QualType EltTy)
If E references a parameter with pass_object_size info or a constant array size modifier,...
@ ForceLeftToRight
! Language semantics require left-to-right evaluation.
@ Default
! No language constraints on evaluation order.
@ ForceRightToLeft
! Language semantics require right-to-left evaluation.
llvm::Value * EmitIvarOffsetAsPointerDiff(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)
RValue EmitCUDAKernelCallExpr(const CUDAKernelCallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
RValue EmitLoadOfAnyValue(LValue V, AggValueSlot Slot=AggValueSlot::ignored(), SourceLocation Loc={})
Like EmitLoadOfLValue but also handles complex and aggregate types.
LValue EmitLValueForField(LValue Base, const FieldDecl *Field, bool IsInBounds=true)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
const TargetInfo & getTarget() const
LValue EmitCompoundAssignmentLValue(const CompoundAssignOperator *E)
bool isInConditionalBranch() const
isInConditionalBranch - Return true if we're currently emitting one branch or the other of a conditio...
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.
LValue EmitHLSLOutArgExpr(const HLSLOutArgExpr *E, CallArgList &Args, QualType Ty)
static bool isVptrCheckRequired(TypeCheckKind TCK, QualType Ty)
Determine whether the pointer type check TCK requires a vptr check.
CGCallee EmitCallee(const Expr *E)
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue=ReturnValueSlot(), llvm::CallBase **CallOrInvoke=nullptr)
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
LValue EmitMatrixSingleSubscriptExpr(const MatrixSingleSubscriptExpr *E)
LValue EmitArraySectionExpr(const ArraySectionExpr *E, bool IsLowerBound=true)
Address GetAddrOfBlockDecl(const VarDecl *var)
llvm::Value * EmitComplexToScalarConversion(ComplexPairTy Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified complex type to the specified destination type,...
void pushCleanupAfterFullExpr(CleanupKind Kind, As... A)
Queue a cleanup to be pushed after finishing the current full-expression, potentially with an active ...
void EmitCfiCheckStub()
Emit a stub for the cross-DSO CFI check function.
void pushFullExprCleanup(CleanupKind kind, As... A)
pushFullExprCleanup - Push a cleanup to be run at the end of the current full-expression.
static Destroyer destroyARCStrongImprecise
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
LValue EmitAggExprToLValue(const Expr *E)
EmitAggExprToLValue - Emit the computation of the specified expression of aggregate type into a tempo...
void SetFPAccuracy(llvm::Value *Val, float Accuracy)
SetFPAccuracy - Set the minimum required accuracy of the given floating point operation,...
Address mergeAddressesInConditionalExpr(Address LHS, Address RHS, llvm::BasicBlock *LHSBlock, llvm::BasicBlock *RHSBlock, llvm::BasicBlock *MergeBlock, QualType MergedType)
Address emitAddrOfImagComponent(Address complex, QualType complexType)
void EmitBoundsCheck(const Expr *ArrayExpr, const Expr *ArrayExprBase, llvm::Value *Index, QualType IndexType, bool Accessed)
Emit a check that Base points into an array object, which we can access at index Index.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
LValue EmitPredefinedLValue(const PredefinedExpr *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...
LValue EmitDeclRefLValue(const DeclRefExpr *E)
LValue EmitStringLiteralLValue(const StringLiteral *E)
AggValueSlot CreateAggTemp(QualType T, const Twine &Name="tmp", RawAddress *Alloca=nullptr)
CreateAggTemp - Create a temporary memory object for the given aggregate type.
RValue getOrCreateOpaqueRValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its RValue mapping if it exists, otherwise create one.
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
CGDebugInfo * getDebugInfo()
llvm::Value * emitScalarConstant(const ConstantEmission &Constant, Expr *E)
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
bool EmitLifetimeStart(llvm::Value *Addr)
Emit a lifetime.begin marker if some criteria are satisfied.
LValue EmitUnsupportedLValue(const Expr *E, const char *Name)
EmitUnsupportedLValue - Emit a dummy l-value using the type of E and issue an ErrorUnsupported style ...
LValue MakeRawAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment, AlignmentSource Source=AlignmentSource::Type)
Same as MakeAddrLValue above except that the pointer is known to be unsigned.
llvm::MDNode * buildAllocToken(QualType AllocType)
Build metadata used by the AllocToken instrumentation.
RValue EmitCXXMemberCallExpr(const CXXMemberCallExpr *E, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke=nullptr)
LValue EmitLValueForFieldInitialization(LValue Base, const FieldDecl *Field)
EmitLValueForFieldInitialization - Like EmitLValueForField, except that if the Field is a reference,...
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
Address emitBlockByrefAddress(Address baseAddr, const VarDecl *V, bool followForward=true)
BuildBlockByrefAddress - Computes the location of the data in a variable which is declared as __block...
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
LValue getOrCreateOpaqueLValueMapping(const OpaqueValueExpr *e)
Given an opaque value expression, return its LValue mapping if it exists, otherwise create one.
bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty, SourceLocation Loc)
Check if the scalar Value is within the valid range for the given type Ty.
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
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
llvm::ConstantInt * getUBSanFunctionTypeHash(QualType T) const
Return a type hash constant for a function instrumented by -fsanitize=function.
LValue EmitHLSLArrayAssignLValue(const BinaryOperator *E)
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
LValue EmitVAArgExprLValue(const VAArgExpr *E)
bool IsInPreservedAIRegion
True if CodeGen currently emits code inside presereved access index region.
RValue EmitAnyExprToTemp(const Expr *E)
EmitAnyExprToTemp - Similarly to EmitAnyExpr(), however, the result will always be accessible even if...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
LValue EmitStmtExprLValue(const StmtExpr *E)
llvm::Value * EmitARCLoadWeakRetained(Address addr)
i8* @objc_loadWeakRetained(i8** addr)
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates a alloca and inserts it into the entry block.
llvm::Value * EmitWithOriginalRHSBitfieldAssignment(const BinaryOperator *E, llvm::Value **Previous, QualType *SrcType)
Retrieve the implicit cast expression of the rhs in a binary operator expression by passing pointers ...
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
LValue EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E)
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
Address EmitArrayToPointerDecay(const Expr *Array, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
void pushLifetimeExtendedDestroy(CleanupKind kind, Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
RValue EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, const CallExpr *E, ReturnValueSlot ReturnValue)
RValue GetUndefRValue(QualType Ty)
GetUndefRValue - Get an appropriate 'undef' rvalue for the given type.
llvm::Instruction * getPostAllocaInsertPoint()
Return PostAllocaInsertPt.
void EmitAllocToken(llvm::CallBase *CB, QualType AllocType)
Emit and set additional metadata used by the AllocToken instrumentation.
LValue EmitComplexAssignmentLValue(const BinaryOperator *E)
Emit an l-value for an assignment (simple or compound) of complex type.
LValue EmitCastLValue(const CastExpr *E)
EmitCastLValue - Casts are never lvalues unless that cast is to a reference type.
llvm::Value * EmitPointerArithmetic(const BinaryOperator *BO, Expr *pointerOperand, llvm::Value *pointer, Expr *indexOperand, llvm::Value *index, bool isSubtraction)
Emit pointer + index arithmetic.
LValue EmitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *E)
LValue EmitLoadOfPointerLValue(Address Ptr, const PointerType *PtrTy)
llvm::Value * EmitCheckValue(llvm::Value *V)
Convert a value into a format suitable for passing to a runtime sanitizer handler.
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
RValue EmitAnyExpr(const Expr *E, AggValueSlot aggSlot=AggValueSlot::ignored(), bool ignoreResult=false)
EmitAnyExpr - Emit code to compute the specified expression which can have any type.
LValue EmitExtVectorElementExpr(const ExtVectorElementExpr *E)
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
RValue EmitUnsupportedRValue(const Expr *E, const char *Name)
EmitUnsupportedRValue - Emit a dummy r-value using the type of E and issue an ErrorUnsupported style ...
CleanupKind getCleanupKind(QualType::DestructionKind kind)
std::pair< LValue, LValue > EmitHLSLOutArgLValues(const HLSLOutArgExpr *E, QualType Ty)
LValue EmitObjCSelectorLValue(const ObjCSelectorExpr *E)
llvm::Type * ConvertTypeForMem(QualType T)
LValue EmitCallExprLValue(const CallExpr *E, llvm::CallBase **CallOrInvoke=nullptr)
RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc)
llvm::Value * EmitARCLoadWeak(Address addr)
i8* @objc_loadWeak(i8** addr) Essentially objc_autorelease(objc_loadWeakRetained(addr)).
LValue EmitLValueForLambdaField(const FieldDecl *Field)
void markStmtMaybeUsed(const Stmt *S)
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
llvm::Value * EmitIvarOffset(const ObjCInterfaceDecl *Interface, const ObjCIvarDecl *Ivar)
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
void FlattenAccessAndTypeLValue(LValue LVal, SmallVectorImpl< LValue > &AccessList)
LValue EmitCoyieldLValue(const CoyieldExpr *E)
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
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.
llvm::SmallVector< const ParmVarDecl *, 4 > FnArgs
Save Parameter Decl for coroutine.
void EmitCXXTemporary(const CXXTemporary *Temporary, QualType TempType, Address Ptr)
Emits all the code to cause the given temporary to be cleaned up.
llvm::Value * authPointerToPointerCast(llvm::Value *ResultPtr, QualType SourceType, QualType DestType)
LValue EmitUnaryOpLValue(const UnaryOperator *E)
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
bool LValueIsSuitableForInlineAtomic(LValue Src)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
LValue EmitCheckedLValue(const Expr *E, TypeCheckKind TCK)
Same as EmitLValue but additionally we generate checking code to guard against undefined behavior.
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...
Address EmitLoadOfReference(LValue RefLVal, LValueBaseInfo *PointeeBaseInfo=nullptr, TBAAAccessInfo *PointeeTBAAInfo=nullptr)
RValue EmitRValueForField(LValue LV, const FieldDecl *FD, SourceLocation Loc)
llvm::Value * EmitObjCExtendObjectLifetime(QualType T, llvm::Value *Ptr)
LValue EmitCXXBindTemporaryLValue(const CXXBindTemporaryExpr *E)
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
bool sanitizePerformTypeCheck() const
Whether any type-checking sanitizers are enabled.
Address EmitExtVectorElementLValue(LValue V)
Generates lvalue for partial ext_vector access.
llvm::Value * EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef< llvm::Value * > IdxList, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, const Twine &Name="")
Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to detect undefined behavior whe...
void EmitInitializationToLValue(const Expr *E, LValue LV, AggValueSlot::IsZeroed_t IsZeroed=AggValueSlot::IsNotZeroed)
EmitInitializationToLValue - Emit an initializer to an LValue.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
Address emitAddrOfRealComponent(Address complex, QualType complexType)
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
RValue EmitLoadOfExtVectorElementLValue(LValue V)
static bool hasAggregateEvaluationKind(QualType T)
static bool IsWrappedCXXThis(const Expr *E)
Check if E is a C++ "this" pointer wrapped in value-preserving casts.
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::Value * EmitMatrixIndexExpr(const Expr *E)
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,...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
const CallExpr * MustTailCall
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
llvm::Value * EmitLoadOfCountedByField(const Expr *Base, const FieldDecl *FD, const FieldDecl *CountDecl)
Build an expression accessing the "counted_by" field.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitUnreachable(SourceLocation Loc)
Emit a reached-unreachable diagnostic if Loc is valid and runtime checking is enabled.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
LValue EmitCXXTypeidLValue(const CXXTypeidExpr *E)
llvm::Function * generateDestroyHelper(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray, const VarDecl *VD)
generateDestroyHelper - Generates a helper function which, when invoked, destroys the given object.
LValue EmitMemberExpr(const MemberExpr *E)
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
ConstantEmission tryEmitAsConstant(const DeclRefExpr *RefExpr)
Try to emit a reference to the given value without producing it as an l-value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
void EmitStoreThroughGlobalRegLValue(RValue Src, LValue Dst)
Store of global named registers are always calls to intrinsics.
bool isOpaqueValueEmitted(const OpaqueValueExpr *E)
isOpaqueValueEmitted - Return true if the opaque value expression has already been emitted.
std::pair< llvm::Value *, CGPointerAuthInfo > EmitOrigPointerRValue(const Expr *E)
Retrieve a pointer rvalue and its ptrauth info.
llvm::Value * EmitARCStoreWeak(Address addr, llvm::Value *value, bool ignored)
i8* @objc_storeWeak(i8** addr, i8* value) Returns value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
RValue EmitCXXOperatorMemberCallExpr(const CXXOperatorCallExpr *E, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue, llvm::CallBase **CallOrInvoke)
static Destroyer destroyARCStrongPrecise
static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts)
getAccessedFieldNo - Given an encoded value and a result number, return the input field number being ...
llvm::Value * EmitScalarConversion(llvm::Value *Src, QualType SrcTy, QualType DstTy, SourceLocation Loc)
Emit a conversion from the specified type to the specified destination type, both of which are LLVM s...
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
static bool ShouldNullCheckClassCastValue(const CastExpr *Cast)
llvm::Value * EmitNonNullRValueCheck(RValue RV, QualType T)
Create a check that a scalar RValue is non-null.
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
llvm::Value * EmitDynamicCast(Address V, const CXXDynamicCastExpr *DCE)
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
llvm::Value * EmitCXXTypeidExpr(const CXXTypeidExpr *E)
This class organizes the cross-function state that is used while generating LLVM code.
void EmitExplicitCastExprType(const ExplicitCastExpr *E, CodeGenFunction *CGF=nullptr)
Emit type info if type of an expression is a variably modified type.
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.
CGDebugInfo * getModuleDebugInfo()
llvm::Constant * getRawFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return a function pointer for a reference to the given function.
llvm::FunctionCallee getAddrAndTypeOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
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.
llvm::Constant * getFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return the ABI-correct function pointer value for a reference to the given function.
const LangOptions & getLangOpts() const
CGCUDARuntime & getCUDARuntime()
Return a reference to the configured CUDA runtime.
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
CGPointerAuthInfo getPointerAuthInfoForPointeeType(QualType type)
llvm::GlobalValue::LinkageTypes getLLVMLinkageVarDefinition(const VarDecl *VD)
Returns LLVM linkage for a declarator.
CGCXXABI & getCXXABI() const
ConstantAddress GetWeakRefReference(const ValueDecl *VD)
Get a reference to the target of VD.
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
TBAAAccessInfo getTBAAAccessInfo(QualType AccessType)
getTBAAAccessInfo - Get TBAA information that describes an access to an object of the given type.
ASTContext & getContext() const
TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, TBAAAccessInfo TargetInfo)
mergeTBAAInfoForCast - Get merged TBAA information for the purposes of type casts.
llvm::Constant * GetAddrOfGlobalVar(const VarDecl *D, llvm::Type *Ty=nullptr, ForDefinition_t IsForDefinition=NotForDefinition)
Return the llvm::Constant for the address of the given global variable.
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
CharUnits getNaturalPointeeTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr)
llvm::LLVMContext & getLLVMContext()
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, const Expr *Inner)
Returns a pointer to a global variable representing a temporary with static or thread storage duratio...
LangAS GetGlobalConstantAddressSpace() const
Return the AST address space of constant literal, which is used to emit the constant literal as globa...
const CGRecordLayout & getCGRecordLayout(const RecordDecl *)
getCGRecordLayout - Return record layout info for the given record decl.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
A specialization of Address that requires the address to be an LLVM Constant.
llvm::Constant * getPointer() const
llvm::Constant * emitAbstract(const Expr *E, QualType T)
Emit the result of the given expression as an abstract constant, asserting that it succeeded.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
AlignmentSource getAlignmentSource() const
LValue - This represents an lvalue references.
llvm::Value * getMatrixRowIdx() const
static LValue MakeMatrixRow(Address Addr, llvm::Value *RowIdx, QualType MatrixTy, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
Expr * getBaseIvarExp() const
llvm::Constant * getExtVectorElts() const
static LValue MakeGlobalReg(llvm::Value *V, CharUnits alignment, QualType type)
bool isObjCStrong() const
bool isGlobalObjCRef() const
bool isVolatileQualified() const
RValue asAggregateRValue() const
llvm::Value * getPointer(CodeGenFunction &CGF) const
llvm::Value * getMatrixIdx() const
llvm::Value * getGlobalReg() const
static LValue MakeAddr(Address Addr, QualType type, ASTContext &Context, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
const Qualifiers & getQuals() const
static LValue MakeExtVectorElt(Address Addr, llvm::Constant *Elts, QualType type, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
Address getAddress() const
unsigned getVRQualifiers() const
bool isExtVectorElt() const
llvm::Value * getVectorIdx() const
void setNontemporal(bool Value)
LValueBaseInfo getBaseInfo() const
void setARCPreciseLifetime(ARCPreciseLifetime_t value)
const CGBitFieldInfo & getBitFieldInfo() const
bool isThreadLocalRef() const
KnownNonNull_t isKnownNonNull() const
TBAAAccessInfo getTBAAInfo() const
void setNonGC(bool Value)
Address getVectorAddress() const
bool isNontemporal() const
static LValue MakeBitfield(Address Addr, const CGBitFieldInfo &Info, QualType type, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
Create a new object to represent a bit-field access.
static LValue MakeVectorElt(Address vecAddress, llvm::Value *Idx, QualType type, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
void setAddress(Address address)
Address getExtVectorAddress() const
static LValue MakeMatrixElt(Address matAddress, llvm::Value *Idx, QualType type, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
Address getMatrixAddress() 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)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
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.
CharUnits getAlignment() const
Return the alignment of this pointer.
llvm::Type * getElementType() const
Return the type of the values stored in this address.
llvm::Value * getPointer() const
unsigned getAddressSpace() const
Return the address space that this address resides in.
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
StringRef getCategory() const
StringRef getMessage() const
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundLiteralExpr - [C99 6.5.2.5].
const Expr * getInitializer() const
Represents a concrete matrix type with constant number of rows and columns.
unsigned getNumColumns() const
Returns the number of columns in the matrix.
unsigned getNumRows() const
Returns the number of rows in the matrix.
RecordDecl * getOuterLexicalRecordContext()
Retrieve the outermost lexically enclosing record context.
A reference to a declared variable, function, enum, etc.
bool refersToEnclosingVariableOrCapture() const
Does this DeclRefExpr refer to an enclosing local or a captured variable?
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getLocation() const
SourceLocation getLocation() const
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
DeclContext * getDeclContext()
ExplicitCastExpr - An explicit cast written in the source code.
This represents one expression.
const Expr * skipRValueSubobjectAdjustments(SmallVectorImpl< const Expr * > &CommaLHS, SmallVectorImpl< SubobjectAdjustment > &Adjustments) const
Walk outwards from an expression we want to bind a reference to and find the expression whose lifetim...
Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY
Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
Decl * getReferencedDeclOfCallee()
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
bool isOBJCGCCandidate(ASTContext &Ctx) const
isOBJCGCCandidate - Return true if this expression may be used in a read/ write barrier.
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
bool isArrow() const
isArrow - Return true if the base expression is a pointer to vector, return false if the base express...
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
const Expr * getBase() const
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
const FieldDecl * findCountedByField() const
Find the FieldDecl specified in a FAM's "counted_by" attribute.
FullExpr - Represents a "full-expression" node.
const Expr * getSubExpr() const
Represents a function declaration or definition.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
FunctionDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Represents a prototype with parameter type info, e.g.
FunctionType - C99 6.7.5.3 - Function Declarators.
GlobalDecl - represents a global declaration.
const Decl * getDecl() const
This class represents temporary values used to represent inout and out arguments in HLSL.
const OpaqueValueExpr * getCastedTemporary() const
const OpaqueValueExpr * getOpaqueArgLValue() const
bool isInOut() const
returns true if the parameter is inout and false if the parameter is out.
const Expr * getWritebackCast() const
const Expr * getArgLValue() const
Return the l-value expression that was written as the argument in source.
Describes an C or C++ initializer list.
bool isTransparent() const
Is this a transparent initializer list (that is, an InitListExpr that is purely syntactic,...
const Expr * getInit(unsigned Init) const
StrictFlexArraysLevelKind
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
StorageDuration getStorageDuration() const
Retrieve the storage duration for the materialized temporary.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
ValueDecl * getExtendingDecl()
Get the declaration which triggered the lifetime-extension of this temporary, if any.
MatrixSingleSubscriptExpr - Matrix single subscript expression for the MatrixType extension when you ...
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
bool isIncomplete() const
QualType getElementType() const
Returns type of the elements being stored in the matrix.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getExprLoc() const LLVM_READONLY
A pointer to member type per C++ 8.3.3 - Pointers to members.
bool isObjCBOOLType(QualType T) const
Returns true if.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
A C++ nested-name-specifier augmented with source location information.
ObjCEncodeExpr, used for @encode in Objective-C.
Represents an ObjC class declaration.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
const Expr * getBase() const
An expression that sends a message to the given Objective-C object or class.
const ObjCMethodDecl * getMethodDecl() const
QualType getReturnType() const
ObjCSelectorExpr used for @selector in Objective-C.
Selector getSelector() const
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
const Expr * getSubExpr() const
Pointer-authentication qualifiers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
[C99 6.4.2.2] - A predefined identifier such as func.
StringRef getIdentKindName() const
PredefinedIdentKind getIdentKind() const
StringLiteral * getFunctionName()
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getColumn() const
Return the presumed column number of this location.
const char * getFilename() const
Return the presumed filename of this location.
unsigned getLine() const
Return the presumed line number of this location.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
semantics_iterator semantics_end()
semantics_iterator semantics_begin()
const Expr *const * const_semantics_iterator
Expr * getResultExpr()
Return the result-bearing expression, or null if there is none.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
PointerAuthQualifier getPointerAuth() const
QualType withoutLocalFastQualifiers() const
bool isNull() const
Return true if this QualType doesn't point to a type yet.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
QualType withCVRQualifiers(unsigned CVR) const
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
The collection of all-type qualifiers we support.
unsigned getCVRQualifiers() const
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_ExplicitNone
This object can be modified without requiring retains or releases.
@ OCL_None
There is no lifetime qualification on this type.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
@ OCL_Autoreleasing
Assigning into this object requires a lifetime extension.
void addCVRQualifiers(unsigned mask)
void addQualifiers(Qualifiers Q)
Add the qualifiers from the given set to this set.
void setAddressSpace(LangAS space)
PointerAuthQualifier getPointerAuth() const
ObjCLifetime getObjCLifetime() const
Represents a struct/union/class.
field_range fields() const
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
StmtClass getStmtClass() const
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
Exposes information about the current target.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual StringRef getABI() const
Get the ABI currently in use.
The base class of the type hierarchy.
bool isBlockPointerType() const
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isPackedVectorBoolType(const ASTContext &ctx) const
bool hasAttr(attr::Kind AK) const
Determine whether this type had the specified attribute applied to it (looking through top-level type...
const ArrayType * castAsArrayTypeUnsafe() const
A variant of castAs<> for array type which silently discards qualifiers from the outermost type.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isConstantArrayType() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isFunctionPointerType() const
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
bool isVariableArrayType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorBoolType() const
bool isBitIntType() const
bool isAnyComplexType() const
bool hasPointeeToCFIUncheckedCalleeFunctionType() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isAtomicType() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjectType() const
Determine whether this type is an object type.
bool isHLSLResourceRecord() const
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool isVectorType() const
bool isAnyPointerType() const
bool isSubscriptableVectorType() const
const T * getAs() const
Member-template getAs<specific type>'.
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
bool isRecordType() const
bool isHLSLResourceRecordArray() const
bool hasBooleanRepresentation() const
Determine whether this type has a boolean representation – i.e., it is a boolean type,...
bool isCFIUncheckedCalleeFunctionType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
SourceLocation getExprLoc() const
Expr * getSubExpr() const
Represents a call to the builtin function __builtin_va_arg.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
TLSKind getTLSKind() const
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
@ TLS_Dynamic
TLS with a dynamic initializer.
@ TLS_None
Not a TLS variable.
Represents a C array with a specified size that is not an integer-constant-expression.
Represents a GCC generic vector type.
unsigned getNumElements() const
AlignmentSource
The source of the alignment of an l-value; an expression of confidence in the alignment actually matc...
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool isEmptyFieldForLayout(const ASTContext &Context, const FieldDecl *FD)
isEmptyFieldForLayout - Return true iff the field is "empty", that is, either a zero-width bit-field ...
@ EHCleanup
Denotes a cleanup that should run when a scope is exited using exceptional control flow (a throw stat...
static AlignmentSource getFieldAlignmentSource(AlignmentSource Source)
Given that the base address has the given alignment source, what's our confidence in the alignment of...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
const AstTypeMatcher< FunctionType > functionType
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
std::optional< llvm::AllocTokenMetadata > getAllocTokenMetadata(QualType T, const ASTContext &Ctx)
Get the information required for construction of an allocation token ID.
QualType inferPossibleType(const CallExpr *E, const ASTContext &Ctx, const CastExpr *CastE)
Infer the possible allocated type from an allocation call expression.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
@ OK_BitField
A bitfield object is a bitfield on a C or C++ record.
@ Asm
Assembly: we accept this only so that we can preprocess it.
StorageDuration
The storage duration for an object (per C++ [basic.stc]).
@ SD_Thread
Thread storage duration.
@ SD_Static
Static storage duration.
@ SD_FullExpression
Full-expression storage duration (for temporaries).
@ SD_Automatic
Automatic storage duration (most local variables).
@ SD_Dynamic
Dynamic storage duration.
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Dtor_Complete
Complete object dtor.
LangAS
Defines the address space values used by the address space qualifier of QualType.
llvm::cl::opt< bool > ClSanitizeGuardChecks
SmallVector< CXXBaseSpecifier *, 4 > CXXCastPath
A simple array of base specifiers.
U cast(CodeGen::Address addr)
LangAS getLangASFromTargetAS(unsigned TargetAS)
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
bool isLambdaMethod(const DeclContext *DC)
@ Other
Other implicit parameter.
@ NOUR_Unevaluated
This name appears in an unevaluated operand.
@ NOUR_Constant
This name appears as a potential result of an lvalue-to-rvalue conversion that is a constant expressi...
__INTPTR_TYPE__ intptr_t
A signed integer type with the property that any valid pointer to void can be converted to this type,...
Structure with information about how a bitfield should be accessed.
CharUnits VolatileStorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned VolatileOffset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned VolatileStorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
unsigned IsSigned
Whether the bit-field is signed.
static Address getAddrOfThreadPrivate(CodeGenFunction &CGF, const VarDecl *VD, Address VDAddr, SourceLocation Loc)
Returns address of the threadprivate variable for the current thread.
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
CharUnits getIntAlign() const
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
unsigned char PointerWidthInBits
The width of a pointer into the generic address space.
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
llvm::PointerType * DefaultPtrTy
LangAS getASTAllocaAddressSpace() const
llvm::MDNode * AccessType
AccessType - The final access type.
uint64_t Offset
Offset - The byte offset of the final access within the base one.
static TBAAAccessInfo getMayAliasInfo()
uint64_t Size
Size - The size of access, in bytes.
llvm::MDNode * BaseType
BaseType - The base/leading access type.
bool isIncomplete() const
EvalResult is a struct with detailed info about an evaluated expression.
APValue Val
Val - This is the value the expression can be folded to.
bool HasSideEffects
Whether the evaluated expression has side effects.
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.
An adjustment to be made to the temporary created when emitting a reference binding,...
@ DerivedToBaseAdjustment
@ MemberPointerAdjustment