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 !
SanOpts.has(SanitizerKind::MemtagStack) &&
624 !
CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) ||
626 OldConditional = OutermostConditional;
627 OutermostConditional =
nullptr;
631 Builder.restoreIP(CGBuilderTy::InsertPoint(
632 Block, llvm::BasicBlock::iterator(
Block->back())));
639 if (OldConditional) {
640 OutermostConditional = OldConditional;
657 switch (Adjustment.Kind) {
661 Adjustment.DerivedToBase.BasePath->path_begin(),
662 Adjustment.DerivedToBase.BasePath->path_end(),
670 "materialized temporary field is not a simple lvalue");
678 E, Object, Ptr, Adjustment.Ptr.MPT,
true);
711 const llvm::Constant *Elts) {
719 Builder.CreateMul(Ptr, Builder.getInt64(0xbf58476d1ce4e5b9u));
721 Builder.CreateXor(A0, Builder.CreateLShr(A0, Builder.getInt64(31)));
722 return Builder.CreateXor(Acc, A1);
739 return SanOpts.has(SanitizerKind::Null) ||
740 SanOpts.has(SanitizerKind::Alignment) ||
741 SanOpts.has(SanitizerKind::ObjectSize) ||
742 SanOpts.has(SanitizerKind::Vptr);
749 llvm::Value *ArraySize) {
756 if (Ptr->getType()->getPointerAddressSpace())
767 auto PtrToAlloca = dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCasts());
769 llvm::Value *IsNonNull =
nullptr;
770 bool IsGuaranteedNonNull =
771 SkippedChecks.
has(SanitizerKind::Null) || PtrToAlloca;
773 llvm::BasicBlock *Done =
nullptr;
774 bool DoneViaNullSanitize =
false;
777 auto CheckHandler = SanitizerHandler::TypeMismatch;
779 {SanitizerKind::SO_Null,
780 SanitizerKind::SO_ObjectSize,
781 SanitizerKind::SO_Alignment},
789 if ((
SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
790 !IsGuaranteedNonNull) {
792 IsNonNull =
Builder.CreateIsNotNull(Ptr);
796 IsGuaranteedNonNull = IsNonNull ==
True;
799 if (!IsGuaranteedNonNull) {
800 if (AllowNullPointers) {
804 DoneViaNullSanitize =
true;
806 Builder.CreateCondBr(IsNonNull, Rest, Done);
809 Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null));
814 if (
SanOpts.has(SanitizerKind::ObjectSize) &&
815 !SkippedChecks.
has(SanitizerKind::ObjectSize) &&
817 uint64_t TySize =
CGM.getMinimumObjectSize(Ty).getQuantity();
818 llvm::Value *Size = llvm::ConstantInt::get(
IntPtrTy, TySize);
820 Size =
Builder.CreateMul(Size, ArraySize);
823 llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
824 if (!ConstantSize || !ConstantSize->isNullValue()) {
831 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
833 llvm::Value *NullIsUnknown =
Builder.getFalse();
834 llvm::Value *Dynamic =
Builder.getFalse();
835 llvm::Value *LargeEnough =
Builder.CreateICmpUGE(
836 Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
838 std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize));
842 llvm::MaybeAlign AlignVal;
843 llvm::Value *PtrAsInt =
nullptr;
845 if (
SanOpts.has(SanitizerKind::Alignment) &&
846 !SkippedChecks.
has(SanitizerKind::Alignment)) {
849 AlignVal =
CGM.getNaturalTypeAlignment(Ty,
nullptr,
nullptr,
854 if (AlignVal && *AlignVal > llvm::Align(1) &&
855 (!PtrToAlloca || PtrToAlloca->getAlign() < *AlignVal)) {
857 llvm::Value *Align =
Builder.CreateAnd(
858 PtrAsInt, llvm::ConstantInt::get(
IntPtrTy, AlignVal->value() - 1));
859 llvm::Value *Aligned =
863 std::make_pair(Aligned, SanitizerKind::SO_Alignment));
867 if (Checks.size() > 0) {
868 llvm::Constant *StaticData[] = {
870 llvm::ConstantInt::get(
Int8Ty, AlignVal ? llvm::Log2(*AlignVal) : 1),
871 llvm::ConstantInt::get(
Int8Ty, TCK)};
872 EmitCheck(Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr);
884 if (
SanOpts.has(SanitizerKind::Vptr) &&
887 SanitizerHandler::DynamicTypeCacheMiss);
891 if (!IsGuaranteedNonNull) {
893 IsNonNull =
Builder.CreateIsNotNull(Ptr);
897 Builder.CreateCondBr(IsNonNull, VptrNotNull, Done);
903 llvm::raw_svector_ostream Out(MangledName);
908 if (!
CGM.getContext().getNoSanitizeList().containsType(SanitizerKind::Vptr,
911 llvm::Value *TypeHash =
912 llvm::ConstantInt::get(
Int64Ty, xxh3_64bits(Out.str()));
926 const int CacheSize = 128;
927 llvm::Type *HashTable = llvm::ArrayType::get(
IntPtrTy, CacheSize);
928 llvm::Value *
Cache =
CGM.CreateRuntimeVariable(HashTable,
929 "__ubsan_vptr_type_cache");
930 llvm::Value *Slot =
Builder.CreateAnd(Hash,
933 llvm::Value *Indices[] = {
Builder.getInt32(0), Slot };
934 llvm::Value *CacheVal =
Builder.CreateAlignedLoad(
942 llvm::Value *EqualHash =
Builder.CreateICmpEQ(CacheVal, Hash);
943 llvm::Constant *StaticData[] = {
947 llvm::ConstantInt::get(
Int8Ty, TCK)
949 llvm::Value *DynamicData[] = { Ptr, Hash };
950 EmitCheck(std::make_pair(EqualHash, SanitizerKind::SO_Vptr),
951 SanitizerHandler::DynamicTypeCacheMiss, StaticData,
959 {DoneViaNullSanitize ? SanitizerKind::SO_Null : SanitizerKind::SO_Vptr},
960 DoneViaNullSanitize ? SanitizerHandler::TypeMismatch
961 : SanitizerHandler::DynamicTypeCacheMiss);
970 uint64_t EltSize =
C.getTypeSizeInChars(EltTy).getQuantity();
978 auto *ParamDecl = dyn_cast<ParmVarDecl>(ArrayDeclRef->getDecl());
982 auto *POSAttr = ParamDecl->getAttr<PassObjectSizeAttr>();
987 int POSType = POSAttr->getType();
988 if (POSType != 0 && POSType != 1)
992 auto PassedSizeIt = SizeArguments.find(ParamDecl);
993 if (PassedSizeIt == SizeArguments.end())
997 assert(LocalDeclMap.count(PassedSizeDecl) &&
"Passed size not loadable");
998 Address AddrOfSize = LocalDeclMap.find(PassedSizeDecl)->second;
1001 llvm::Value *SizeOfElement =
1002 llvm::ConstantInt::get(SizeInBytes->getType(), EltSize);
1003 return Builder.CreateUDiv(SizeInBytes, SizeOfElement);
1012 StrictFlexArraysLevel) {
1015 IndexedType =
Base->getType();
1016 return CGF.
Builder.getInt32(VT->getNumElements());
1021 if (
const auto *CE = dyn_cast<CastExpr>(
Base)) {
1022 if (CE->getCastKind() == CK_ArrayToPointerDecay &&
1023 !CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.
getContext(),
1024 StrictFlexArraysLevel)) {
1027 IndexedType = CE->getSubExpr()->getType();
1029 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
1030 return CGF.
Builder.getInt(CAT->getSize());
1032 if (
const auto *VAT = dyn_cast<VariableArrayType>(AT))
1040 QualType EltTy{
Base->getType()->getPointeeOrArrayElementType(), 0};
1042 IndexedType =
Base->getType();
1067class StructAccessBase
1068 :
public ConstStmtVisitor<StructAccessBase, const Expr *> {
1069 const RecordDecl *ExpectedRD;
1071 bool IsExpectedRecordDecl(
const Expr *E)
const {
1079 StructAccessBase(
const RecordDecl *ExpectedRD) : ExpectedRD(ExpectedRD) {}
1098 const Expr *Visit(
const Expr *E) {
1099 return ConstStmtVisitor<StructAccessBase, const Expr *>::Visit(E);
1102 const Expr *VisitStmt(
const Stmt *S) {
return nullptr; }
1117 const Expr *VisitDeclRefExpr(
const DeclRefExpr *E) {
1118 return IsExpectedRecordDecl(E) ? E :
nullptr;
1120 const Expr *VisitMemberExpr(
const MemberExpr *E) {
1121 if (IsExpectedRecordDecl(E) && E->
isArrow())
1123 const Expr *Res = Visit(E->
getBase());
1124 return !Res && IsExpectedRecordDecl(E) ? E : Res;
1126 const Expr *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
1127 return IsExpectedRecordDecl(E) ? E :
nullptr;
1129 const Expr *VisitCallExpr(
const CallExpr *E) {
1130 return IsExpectedRecordDecl(E) ? E :
nullptr;
1133 const Expr *VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
1134 if (IsExpectedRecordDecl(E))
1138 const Expr *VisitCastExpr(
const CastExpr *E) {
1140 return IsExpectedRecordDecl(E) ? E :
nullptr;
1143 const Expr *VisitParenExpr(
const ParenExpr *E) {
1146 const Expr *VisitUnaryAddrOf(
const UnaryOperator *E) {
1149 const Expr *VisitUnaryDeref(
const UnaryOperator *E) {
1162 int64_t FieldNo = -1;
1171 Indices.emplace_back(CGF.
Builder.getInt32(FieldNo));
1180 Indices.emplace_back(CGF.
Builder.getInt32(FieldNo));
1194 const Expr *StructBase = StructAccessBase(RD).Visit(
Base);
1198 llvm::Value *Res =
nullptr;
1203 Res =
Addr.emitRawPointer(*
this);
1204 }
else if (StructBase->
isLValue()) {
1207 Res =
Addr.emitRawPointer(*
this);
1214 if (Indices.empty())
1217 Indices.push_back(
Builder.getInt32(0));
1241 const Expr *ArrayExprBase,
1242 llvm::Value *IndexVal,
QualType IndexType,
1244 assert(
SanOpts.has(SanitizerKind::ArrayBounds) &&
1245 "should not be called unless adding bounds checks");
1250 *
this, ArrayExprBase, ArrayExprBaseType, StrictFlexArraysLevel);
1253 BoundsVal,
getContext().getSizeType(), Accessed);
1258 llvm::Value *IndexVal,
1260 llvm::Value *BoundsVal,
1261 QualType BoundsType,
bool Accessed) {
1265 auto CheckKind = SanitizerKind::SO_ArrayBounds;
1266 auto CheckHandler = SanitizerHandler::OutOfBounds;
1278 llvm::Value *IndexInst =
Builder.CreateIntCast(IndexVal, Ty, IndexSigned);
1279 llvm::Value *BoundsInst =
Builder.CreateIntCast(BoundsVal, Ty,
false);
1281 llvm::Constant *StaticData[] = {
1287 llvm::Value *Check = Accessed ?
Builder.CreateICmpULT(IndexInst, BoundsInst)
1288 :
Builder.CreateICmpULE(IndexInst, BoundsInst);
1292 llvm::Value *Cmp =
Builder.CreateICmpSGT(
1293 BoundsVal, llvm::ConstantInt::get(BoundsVal->getType(), 0));
1294 Check =
Builder.CreateAnd(Cmp, Check);
1297 EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData,
1307 auto *TypeNameMD = MDB.createString(ATMD->TypeName);
1308 auto *ContainsPtrC =
Builder.getInt1(ATMD->ContainsPointer);
1309 auto *ContainsPtrMD = MDB.createConstant(ContainsPtrC);
1312 return llvm::MDNode::get(
CGM.getLLVMContext(), {TypeNameMD, ContainsPtrMD});
1316 assert(
SanOpts.has(SanitizerKind::AllocToken) &&
1317 "Only needed with -fsanitize=alloc-token");
1318 CB->setMetadata(llvm::LLVMContext::MD_alloc_token,
1330 assert(
SanOpts.has(SanitizerKind::AllocToken) &&
1331 "Only needed with -fsanitize=alloc-token");
1333 CB->setMetadata(llvm::LLVMContext::MD_alloc_token, MDN);
1338 bool isInc,
bool isPre) {
1341 llvm::Value *NextVal;
1343 uint64_t AmountVal = isInc ? 1 : -1;
1344 NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal,
true);
1347 NextVal =
Builder.CreateAdd(InVal.first, NextVal, isInc ?
"inc" :
"dec");
1350 llvm::APFloat FVal(
getContext().getFloatTypeSemantics(ElemTy), 1);
1356 NextVal =
Builder.CreateFAdd(InVal.first, NextVal, isInc ?
"inc" :
"dec");
1364 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*
this,
1369 return isPre ? IncVal : InVal;
1379 DI->EmitExplicitCastType(E->
getType());
1390 if (
auto *constantIdx = dyn_cast<llvm::ConstantInt>(idx)) {
1391 CharUnits offset = constantIdx->getZExtValue() * eltSize;
1405 assert(BO->
isAdditiveOp() &&
"Expect an addition or subtraction.");
1408 bool isSubtraction = BO->
getOpcode() == BO_Sub;
1411 llvm::Value *
index =
nullptr;
1415 std::swap(pointerOperand, indexOperand);
1427 BO, pointerOperand, pointer, indexOperand,
index, isSubtraction);
1434 nullptr, IsKnownNonNull);
1447 if (
const CastExpr *CE = dyn_cast<CastExpr>(E)) {
1448 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(CE))
1451 switch (CE->getCastKind()) {
1455 case CK_AddressSpaceConversion:
1456 if (
auto PtrTy = CE->getSubExpr()->getType()->getAs<
PointerType>()) {
1457 if (PtrTy->getPointeeType()->isVoidType())
1463 CE->getSubExpr(), &InnerBaseInfo, &InnerTBAAInfo, IsKnownNonNull);
1464 if (BaseInfo) *BaseInfo = InnerBaseInfo;
1465 if (TBAAInfo) *TBAAInfo = InnerTBAAInfo;
1471 E->
getType(), &TargetTypeBaseInfo, &TargetTypeTBAAInfo);
1479 BaseInfo->mergeForCast(TargetTypeBaseInfo);
1480 Addr.setAlignment(Align);
1484 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast) &&
1485 CE->getCastKind() == CK_BitCast) {
1493 llvm::Type *ElemTy =
1495 Addr =
Addr.withElementType(ElemTy);
1496 if (CE->getCastKind() == CK_AddressSpaceConversion)
1506 case CK_ArrayToPointerDecay:
1510 case CK_UncheckedDerivedToBase:
1511 case CK_DerivedToBase: {
1518 CE->getSubExpr(), BaseInfo,
nullptr,
1520 CE->getCastKind() == CK_UncheckedDerivedToBase));
1521 auto Derived = CE->getSubExpr()->
getType()->getPointeeCXXRecordDecl();
1523 Addr, Derived, CE->path_begin(), CE->path_end(),
1536 if (UO->getOpcode() == UO_AddrOf) {
1537 LValue LV = CGF.
EmitLValue(UO->getSubExpr(), IsKnownNonNull);
1538 if (BaseInfo) *BaseInfo = LV.getBaseInfo();
1539 if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
1540 return LV.getAddress();
1545 if (
auto *
Call = dyn_cast<CallExpr>(E)) {
1546 switch (
Call->getBuiltinCallee()) {
1549 case Builtin::BIaddressof:
1550 case Builtin::BI__addressof:
1551 case Builtin::BI__builtin_addressof: {
1553 if (BaseInfo) *BaseInfo = LV.getBaseInfo();
1554 if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
1555 return LV.getAddress();
1561 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
1562 if (BO->isAdditiveOp())
1571 true, BaseInfo, TBAAInfo, IsKnownNonNull);
1581 if (IsKnownNonNull && !
Addr.isKnownNonNull())
1582 Addr.setKnownNonNull();
1589 return CGM.getCXXABI().EmitMemberPointerIsNotNull(*
this,
V, MPT);
1590 return Builder.CreateICmpNE(
V, llvm::Constant::getNullValue(
V->getType()));
1601 llvm::Value *
U = llvm::UndefValue::get(EltTy);
1616 llvm_unreachable(
"bad evaluation kind");
1641 if (
const auto *CE = dyn_cast<CastExpr>(
Base)) {
1642 Base = CE->getSubExpr();
1643 }
else if (
const auto *PE = dyn_cast<ParenExpr>(
Base)) {
1644 Base = PE->getSubExpr();
1645 }
else if (
const auto *UO = dyn_cast<UnaryOperator>(
Base)) {
1646 if (UO->getOpcode() == UO_Extension)
1647 Base = UO->getSubExpr();
1665 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
1668 SkippedChecks.
set(SanitizerKind::Alignment,
true);
1670 SkippedChecks.
set(SanitizerKind::Null,
true);
1697 CGM.runWithSufficientStackSpace(
1698 E->
getExprLoc(), [&] { LV = EmitLValueHelper(E, IsKnownNonNull); });
1710 return cast<CallExpr>(SE)->getCallReturnType(Ctx)->getPointeeType();
1713LValue CodeGenFunction::EmitLValueHelper(
const Expr *E,
1715 ApplyDebugLocation DL(*
this, E);
1719 case Expr::ObjCPropertyRefExprClass:
1720 llvm_unreachable(
"cannot emit a property reference directly");
1722 case Expr::ObjCSelectorExprClass:
1724 case Expr::ObjCIsaExprClass:
1726 case Expr::BinaryOperatorClass:
1728 case Expr::CompoundAssignOperatorClass: {
1730 if (
const AtomicType *AT = Ty->
getAs<AtomicType>())
1731 Ty = AT->getValueType();
1736 case Expr::CallExprClass:
1737 case Expr::CXXMemberCallExprClass:
1738 case Expr::CXXOperatorCallExprClass:
1739 case Expr::UserDefinedLiteralClass:
1741 case Expr::CXXRewrittenBinaryOperatorClass:
1744 case Expr::VAArgExprClass:
1746 case Expr::DeclRefExprClass:
1748 case Expr::ConstantExprClass: {
1750 if (llvm::Value *
Result = ConstantEmitter(*this).tryEmitConstantExpr(CE)) {
1756 case Expr::ParenExprClass:
1758 case Expr::GenericSelectionExprClass:
1761 case Expr::PredefinedExprClass:
1763 case Expr::StringLiteralClass:
1765 case Expr::ObjCEncodeExprClass:
1767 case Expr::PseudoObjectExprClass:
1769 case Expr::InitListExprClass:
1771 case Expr::CXXTemporaryObjectExprClass:
1772 case Expr::CXXConstructExprClass:
1774 case Expr::CXXBindTemporaryExprClass:
1776 case Expr::CXXUuidofExprClass:
1778 case Expr::LambdaExprClass:
1781 case Expr::ExprWithCleanupsClass: {
1784 LValue LV =
EmitLValue(cleanups->getSubExpr(), IsKnownNonNull);
1785 if (LV.isSimple()) {
1788 Address
Addr = LV.getAddress();
1789 llvm::Value *
V =
Addr.getBasePointer();
1790 Scope.ForceCleanup({&
V});
1791 Addr.replaceBasePointer(
V);
1793 LV.getBaseInfo(), LV.getTBAAInfo());
1800 case Expr::CXXDefaultArgExprClass: {
1803 return EmitLValue(DAE->getExpr(), IsKnownNonNull);
1805 case Expr::CXXDefaultInitExprClass: {
1808 return EmitLValue(DIE->getExpr(), IsKnownNonNull);
1810 case Expr::CXXTypeidExprClass:
1813 case Expr::ObjCMessageExprClass:
1815 case Expr::ObjCIvarRefExprClass:
1817 case Expr::StmtExprClass:
1819 case Expr::UnaryOperatorClass:
1821 case Expr::ArraySubscriptExprClass:
1823 case Expr::MatrixSingleSubscriptExprClass:
1825 case Expr::MatrixSubscriptExprClass:
1827 case Expr::ArraySectionExprClass:
1829 case Expr::ExtVectorElementExprClass:
1831 case Expr::CXXThisExprClass:
1833 case Expr::MemberExprClass:
1835 case Expr::CompoundLiteralExprClass:
1837 case Expr::ConditionalOperatorClass:
1839 case Expr::BinaryConditionalOperatorClass:
1841 case Expr::ChooseExprClass:
1843 case Expr::OpaqueValueExprClass:
1845 case Expr::SubstNonTypeTemplateParmExprClass:
1848 case Expr::ImplicitCastExprClass:
1849 case Expr::CStyleCastExprClass:
1850 case Expr::CXXFunctionalCastExprClass:
1851 case Expr::CXXStaticCastExprClass:
1852 case Expr::CXXDynamicCastExprClass:
1853 case Expr::CXXReinterpretCastExprClass:
1854 case Expr::CXXConstCastExprClass:
1855 case Expr::CXXAddrspaceCastExprClass:
1856 case Expr::ObjCBridgedCastExprClass:
1859 case Expr::MaterializeTemporaryExprClass:
1862 case Expr::CoawaitExprClass:
1864 case Expr::CoyieldExprClass:
1866 case Expr::PackIndexingExprClass:
1868 case Expr::HLSLOutArgExprClass:
1869 llvm_unreachable(
"cannot emit a HLSL out argument directly");
1876 assert(
type.isCanonical());
1877 assert(!
type->isReferenceType());
1885 if (
const auto *RT = dyn_cast<RecordType>(
type))
1886 if (
const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
1887 RD = RD->getDefinitionOrSelf();
1888 if (RD->hasMutableFields() || !RD->isTrivial())
1910 if (
const auto *ref = dyn_cast<ReferenceType>(
type)) {
1934 }
else if (
const auto *var = dyn_cast<VarDecl>(
Value)) {
1944 bool resultIsReference;
1950 resultIsReference =
false;
1956 resultIsReference =
true;
1977 auto *MD = dyn_cast_or_null<CXXMethodDecl>(
CurCodeDecl);
1978 if (
isLambdaMethod(MD) && MD->getOverloadedOperator() == OO_Call) {
1981 if (
const VarDecl *VD = dyn_cast<const VarDecl>(D)) {
1982 if (!VD->hasAttr<CUDADeviceAttr>()) {
2005 if (resultIsReference)
2032 assert(Constant &&
"not a constant");
2048 llvm::APInt &
Min, llvm::APInt &End,
2049 bool StrictEnums,
bool IsBool) {
2051 bool IsRegularCPlusPlusEnum =
2052 CGF.
getLangOpts().CPlusPlus && StrictEnums && ED && !ED->isFixed();
2053 if (!IsBool && !IsRegularCPlusPlusEnum)
2060 ED->getValueRange(End,
Min);
2065llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
2066 llvm::APInt
Min, End;
2072 return MDHelper.createRange(
Min, End);
2080 }
else if (
CGM.getCodeGenOpts().OptimizationLevel > 0) {
2081 if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) {
2082 Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
2083 Load->setMetadata(llvm::LLVMContext::MD_noundef,
2084 llvm::MDNode::get(
CGM.getLLVMContext(), {}));
2091 bool HasBoolCheck =
SanOpts.has(SanitizerKind::Bool);
2092 bool HasEnumCheck =
SanOpts.has(SanitizerKind::Enum);
2093 if (!HasBoolCheck && !HasEnumCheck)
2098 bool NeedsBoolCheck = HasBoolCheck && IsBool;
2100 if (!NeedsBoolCheck && !NeedsEnumCheck)
2110 if (NeedsEnumCheck &&
2111 getContext().isTypeIgnoredBySanitizer(SanitizerKind::Enum, Ty))
2114 llvm::APInt
Min, End;
2119 NeedsEnumCheck ? SanitizerKind::SO_Enum : SanitizerKind::SO_Bool;
2122 auto CheckHandler = SanitizerHandler::LoadInvalidValue;
2127 Check =
Builder.CreateICmpULE(
Value, llvm::ConstantInt::get(Ctx, End));
2129 llvm::Value *Upper =
2130 Builder.CreateICmpSLE(
Value, llvm::ConstantInt::get(Ctx, End));
2131 llvm::Value *Lower =
2133 Check =
Builder.CreateAnd(Upper, Lower);
2137 EmitCheck(std::make_pair(Check, Kind), CheckHandler, StaticArgs,
Value);
2146 bool isNontemporal) {
2147 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
Addr.getBasePointer()))
2148 if (GV->isThreadLocal())
2154 if (ClangVecTy->isPackedVectorBoolType(
getContext())) {
2156 unsigned ValNumElems =
2159 auto *RawIntV =
Builder.CreateLoad(
Addr, Volatile,
"load_bits");
2160 const auto *RawIntTy = RawIntV->getType();
2161 assert(RawIntTy->isIntegerTy() &&
"compressed iN storage for bitvectors");
2163 auto *PaddedVecTy = llvm::FixedVectorType::get(
2164 Builder.getInt1Ty(), RawIntTy->getPrimitiveSizeInBits());
2165 llvm::Value *
V =
Builder.CreateBitCast(RawIntV, PaddedVecTy);
2178 if (VTy != NewVecTy) {
2180 llvm::Value *
V =
Builder.CreateLoad(Cast, Volatile,
"loadVecN");
2181 unsigned OldNumElements = VTy->getNumElements();
2183 std::iota(Mask.begin(), Mask.end(), 0);
2184 V =
Builder.CreateShuffleVector(
V, Mask,
"extractVec");
2199 llvm::LoadInst *Load =
Builder.CreateLoad(
Addr, Volatile);
2200 if (isNontemporal) {
2201 llvm::MDNode *Node = llvm::MDNode::get(
2202 Load->getContext(), llvm::ConstantAsMetadata::get(
Builder.getInt32(1)));
2203 Load->setMetadata(llvm::LLVMContext::MD_nontemporal, Node);
2206 CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
2218 Ty = AtomicTy->getValueType();
2226 if (StoreTy->isVectorTy() && StoreTy->getScalarSizeInBits() >
2231 unsigned MemNumElems = StoreTy->getPrimitiveSizeInBits();
2252 Ty = AtomicTy->getValueType();
2258 auto *PaddedVecTy = llvm::FixedVectorType::get(
2259 Builder.getInt1Ty(), RawIntTy->getPrimitiveSizeInBits());
2279 bool IsVector =
true) {
2280 auto *ArrayTy = dyn_cast<llvm::ArrayType>(
Addr.getElementType());
2281 if (ArrayTy && IsVector) {
2282 auto *VectorTy = llvm::FixedVectorType::get(ArrayTy->getElementType(),
2283 ArrayTy->getNumElements());
2285 return Addr.withElementType(VectorTy);
2287 auto *VectorTy = dyn_cast<llvm::VectorType>(
Addr.getElementType());
2288 if (VectorTy && !IsVector) {
2289 auto *ArrayTy = llvm::ArrayType::get(
2290 VectorTy->getElementType(),
2293 return Addr.withElementType(ArrayTy);
2305 value->getType()->isVectorTy());
2307 lvalue.getBaseInfo(), lvalue.getTBAAInfo(), isInit,
2308 lvalue.isNontemporal());
2315 bool isInit,
bool isNontemporal) {
2316 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
Addr.getBasePointer()))
2317 if (GV->isThreadLocal())
2325 if (
auto *VecTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2327 CGM.getABIInfo().getOptimalVectorMemoryType(VecTy,
getLangOpts());
2328 if (!ClangVecTy->isPackedVectorBoolType(
getContext()) &&
2329 VecTy != NewVecTy) {
2331 VecTy->getNumElements());
2332 std::iota(Mask.begin(), Mask.begin() + VecTy->getNumElements(), 0);
2336 Mask,
"extractVec");
2339 if (
Addr.getElementType() != SrcTy)
2340 Addr =
Addr.withElementType(SrcTy);
2357 if (isNontemporal) {
2358 llvm::MDNode *Node =
2359 llvm::MDNode::get(Store->getContext(),
2360 llvm::ConstantAsMetadata::get(
Builder.getInt32(1)));
2361 Store->setMetadata(llvm::LLVMContext::MD_nontemporal, Node);
2364 CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
2383 assert(LV.getType()->isConstantMatrixType());
2385 LV.setAddress(
Addr);
2401 llvm_unreachable(
"bad evaluation kind");
2464 if (
CGM.getCodeGenOpts().OptimizationLevel > 0) {
2466 llvm::MatrixBuilder MB(
Builder);
2467 MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened());
2469 llvm::LoadInst *Load =
2479 unsigned NumLanes = NumCols;
2483 llvm::Constant *ColConstsIndices =
nullptr;
2484 llvm::MatrixBuilder MB(
Builder);
2488 NumLanes = llvm::cast<llvm::FixedVectorType>(ColConstsIndices->getType())
2492 llvm::Type *RowTy = llvm::FixedVectorType::get(ElemTy, NumLanes);
2493 llvm::Value *
Result = llvm::PoisonValue::get(RowTy);
2495 for (
unsigned Col = 0; Col < NumLanes; ++Col) {
2496 llvm::Value *ColIdx;
2497 if (ColConstsIndices)
2498 ColIdx = ColConstsIndices->getAggregateElement(Col);
2500 ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
2501 bool IsMatrixRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
2503 llvm::Value *EltIndex =
2504 MB.CreateIndex(Row, ColIdx, NumRows, NumCols, IsMatrixRowMajor);
2505 llvm::Value *Elt =
Builder.CreateExtractElement(MatrixVec, EltIndex);
2506 llvm::Value *Lane = llvm::ConstantInt::get(
Builder.getInt32Ty(), Col);
2513 assert(LV.
isBitField() &&
"Unknown LValue type!");
2531 const unsigned StorageSize =
2534 assert(
static_cast<unsigned>(Offset + Info.
Size) <= StorageSize);
2535 unsigned HighBits = StorageSize - Offset - Info.
Size;
2537 Val =
Builder.CreateShl(Val, HighBits,
"bf.shl");
2538 if (Offset + HighBits)
2539 Val =
Builder.CreateAShr(Val, Offset + HighBits,
"bf.ashr");
2542 Val =
Builder.CreateLShr(Val, Offset,
"bf.lshr");
2543 if (
static_cast<unsigned>(Offset) + Info.
Size < StorageSize)
2545 Val, llvm::APInt::getLowBitsSet(StorageSize, Info.
Size),
"bf.clear");
2561 llvm::Type *DstTy = llvm::FixedVectorType::get(Vec->getType(), 1);
2562 llvm::Value *
Zero = llvm::Constant::getNullValue(
CGM.Int64Ty);
2563 Vec =
Builder.CreateInsertElement(DstTy, Vec,
Zero,
"cast.splat");
2573 llvm::Value *Elt = llvm::ConstantInt::get(
SizeTy, InIdx);
2575 llvm::Value *Element =
Builder.CreateExtractElement(Vec, Elt);
2578 if (Element->getType()->getPrimitiveSizeInBits() >
2579 LVTy->getPrimitiveSizeInBits())
2580 Element =
Builder.CreateTrunc(Element, LVTy);
2589 for (
unsigned i = 0; i != NumResultElts; ++i)
2592 Vec =
Builder.CreateShuffleVector(Vec, Mask);
2604 llvm::Type *VectorElementTy =
CGM.getTypes().ConvertType(EQT);
2612 Builder.CreateConstInBoundsGEP(CastToPointerElement, ix,
2615 return VectorBasePtrPlusIx;
2621 "Bad type for register variable");
2626 llvm::Type *OrigTy =
CGM.getTypes().ConvertType(LV.
getType());
2627 llvm::Type *Ty = OrigTy;
2628 if (OrigTy->isPointerTy())
2629 Ty =
CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
2630 llvm::Type *Types[] = { Ty };
2632 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
2634 F, llvm::MetadataAsValue::get(Ty->getContext(), RegName));
2635 if (OrigTy->isPointerTy())
2653 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2655 CGM.getDataLayout().getPrefTypeAlign(ElemTy));
2657 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2658 "vector element type must be at least byte-sized");
2661 if (Val->getType()->getPrimitiveSizeInBits() <
2662 ElemTy->getScalarSizeInBits())
2663 Val =
Builder.CreateZExt(Val, ElemTy->getScalarType());
2666 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2668 Builder.CreateGEP(DstAddr, {
Zero, Idx}, DestAddrTy, ElemAlign);
2676 llvm::Type *VecTy = Vec->getType();
2679 if (SrcVal->getType()->getPrimitiveSizeInBits() <
2680 VecTy->getScalarSizeInBits())
2681 SrcVal =
Builder.CreateZExt(SrcVal, VecTy->getScalarType());
2683 auto *IRStoreTy = dyn_cast<llvm::IntegerType>(Vec->getType());
2685 auto *IRVecTy = llvm::FixedVectorType::get(
2686 Builder.getInt1Ty(), IRStoreTy->getPrimitiveSizeInBits());
2687 Vec =
Builder.CreateBitCast(Vec, IRVecTy);
2694 if (
auto *EltTy = dyn_cast<llvm::FixedVectorType>(SrcVal->getType());
2695 EltTy && EltTy->getNumElements() == 1)
2696 SrcVal =
Builder.CreateBitCast(SrcVal, EltTy->getElementType());
2702 Vec =
Builder.CreateBitCast(Vec, IRStoreTy);
2726 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2728 CGM.getDataLayout().getPrefTypeAlign(ElemTy));
2730 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2731 "matrix element type must be at least byte-sized");
2734 if (Val->getType()->getPrimitiveSizeInBits() <
2735 ElemTy->getScalarSizeInBits())
2736 Val =
Builder.CreateZExt(Val, ElemTy->getScalarType());
2739 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2741 Builder.CreateGEP(DstAddr, {
Zero, Idx}, DestAddrTy, ElemAlign);
2747 if (
CGM.getCodeGenOpts().OptimizationLevel > 0) {
2749 llvm::MatrixBuilder MB(
Builder);
2750 MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened());
2755 Builder.CreateInsertElement(Load, InsertVal, Idx,
"matins");
2766 "Store through matrix row LValues is only implemented for HLSL!");
2772 unsigned NumLanes = NumCols;
2776 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2780 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2781 "matrix element type must be at least byte-sized");
2784 if (RowVal->getType()->getScalarType()->getPrimitiveSizeInBits() <
2785 ElemTy->getScalarSizeInBits()) {
2787 llvm::Type *StorageElmTy = llvm::FixedVectorType::get(
2788 ElemTy->getScalarType(), RowValVecTy->getNumElements());
2789 RowVal =
Builder.CreateZExt(RowVal, StorageElmTy);
2792 llvm::MatrixBuilder MB(
Builder);
2794 llvm::Constant *ColConstsIndices =
nullptr;
2798 llvm::cast<llvm::FixedVectorType>(ColConstsIndices->getType())
2803 for (
unsigned Col = 0; Col < NumLanes; ++Col) {
2804 llvm::Value *ColIdx;
2805 if (ColConstsIndices)
2806 ColIdx = ColConstsIndices->getAggregateElement(Col);
2808 ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
2809 bool IsMatrixRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
2811 llvm::Value *EltIndex =
2812 MB.CreateIndex(Row, ColIdx, NumRows, NumCols, IsMatrixRowMajor);
2813 llvm::Value *Lane = llvm::ConstantInt::get(
Builder.getInt32Ty(), Col);
2814 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2815 llvm::Value *NewElt =
Builder.CreateExtractElement(RowVal, Lane);
2817 Builder.CreateGEP(DstAddr, {
Zero, EltIndex}, DestAddrTy, ElemAlign);
2824 assert(Dst.
isBitField() &&
"Unknown LValue type");
2839 llvm_unreachable(
"present but none");
2874 CGM.getObjCRuntime().EmitObjCWeakAssign(*
this, src, LvalueDst);
2886 llvm::Value *RHS = dst.emitRawPointer(*
this);
2887 RHS =
Builder.CreatePtrToInt(RHS, ResultType,
"sub.ptr.rhs.cast");
2889 ResultType,
"sub.ptr.lhs.cast");
2890 llvm::Value *BytesBetween =
Builder.CreateSub(LHS, RHS,
"ivar.offset");
2891 CGM.getObjCRuntime().EmitObjCIvarAssign(*
this, src, dst, BytesBetween);
2893 CGM.getObjCRuntime().EmitObjCGlobalAssign(*
this, src, LvalueDst,
2897 CGM.getObjCRuntime().EmitObjCStrongCastAssign(*
this, src, LvalueDst);
2901 assert(Src.
isScalar() &&
"Can't emit an agg store with this method");
2917 llvm::Value *MaskedVal = SrcVal;
2919 const bool UseVolatile =
2922 const unsigned StorageSize =
2927 if (StorageSize != Info.
Size) {
2928 assert(StorageSize > Info.
Size &&
"Invalid bitfield size.");
2935 SrcVal, llvm::APInt::getLowBitsSet(StorageSize, Info.
Size),
2939 SrcVal =
Builder.CreateShl(SrcVal, Offset,
"bf.shl");
2943 Val, ~llvm::APInt::getBitsSet(StorageSize, Offset, Offset + Info.
Size),
2947 SrcVal =
Builder.CreateOr(Val, SrcVal,
"bf.set");
2949 assert(Offset == 0);
2956 CGM.getCodeGenOpts().ForceAAPCSBitfieldLoad)
2957 Builder.CreateLoad(Ptr,
true,
"bf.load");
2966 llvm::Value *ResultVal = MaskedVal;
2970 assert(Info.
Size <= StorageSize);
2971 unsigned HighBits = StorageSize - Info.
Size;
2973 ResultVal =
Builder.CreateShl(ResultVal, HighBits,
"bf.result.shl");
2974 ResultVal =
Builder.CreateAShr(ResultVal, HighBits,
"bf.result.ashr");
2990 SrcVal->getType()->getScalarSizeInBits())
2999 if (!DestAddrTy->isVectorTy()) {
3001 "this should only occur for non-vector l-values");
3014 CGM.getDataLayout().getPrefTypeAlign(DestAddrTy->getScalarType()));
3015 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
3017 for (
unsigned I = 0; I != NumSrcElts; ++I) {
3018 llvm::Value *Val = VTy ?
Builder.CreateExtractElement(
3019 SrcVal, llvm::ConstantInt::get(
Int32Ty, I))
3026 DstElemAddr =
Builder.CreateGEP(
3027 DstAddr, {
Zero, llvm::ConstantInt::get(
Int32Ty, FieldNo)},
3028 DestAddrTy, ElemAlign);
3037 llvm::Type *VecTy = Vec->getType();
3040 unsigned NumSrcElts = VTy->getNumElements();
3042 if (NumDstElts == NumSrcElts) {
3047 for (
unsigned i = 0; i != NumSrcElts; ++i)
3050 Vec =
Builder.CreateShuffleVector(SrcVal, Mask);
3051 }
else if (NumDstElts > NumSrcElts) {
3057 for (
unsigned i = 0; i != NumSrcElts; ++i)
3058 ExtMask.push_back(i);
3059 ExtMask.resize(NumDstElts, -1);
3060 llvm::Value *ExtSrcVal =
Builder.CreateShuffleVector(SrcVal, ExtMask);
3063 for (
unsigned i = 0; i != NumDstElts; ++i)
3073 for (
unsigned i = 0; i != NumSrcElts; ++i)
3075 Vec =
Builder.CreateShuffleVector(Vec, ExtSrcVal, Mask);
3078 llvm_unreachable(
"unexpected shorten vector length");
3084 llvm::Value *Elt = llvm::ConstantInt::get(
SizeTy, InIdx);
3086 Vec =
Builder.CreateInsertElement(Vec, SrcVal, Elt);
3096 "Bad type for register variable");
3099 assert(RegName &&
"Register LValue is not metadata");
3102 llvm::Type *OrigTy =
CGM.getTypes().ConvertType(Dst.
getType());
3103 llvm::Type *Ty = OrigTy;
3104 if (OrigTy->isPointerTy())
3105 Ty =
CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
3106 llvm::Type *Types[] = { Ty };
3108 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
3110 if (OrigTy->isPointerTy())
3113 F, {llvm::MetadataAsValue::get(Ty->getContext(), RegName),
Value});
3121 bool IsMemberAccess=
false) {
3133 LV.setObjCIvar(
false);
3137 LV.setObjCIvar(
true);
3139 LV.setBaseIvarExp(Exp->getBase());
3144 if (
const auto *Exp = dyn_cast<DeclRefExpr>(E)) {
3145 if (
const auto *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
3146 if (VD->hasGlobalStorage()) {
3147 LV.setGlobalObjCRef(
true);
3155 if (
const auto *Exp = dyn_cast<UnaryOperator>(E)) {
3160 if (
const auto *Exp = dyn_cast<ParenExpr>(E)) {
3162 if (LV.isObjCIvar()) {
3169 LV.setObjCIvar(
false);
3174 if (
const auto *Exp = dyn_cast<GenericSelectionExpr>(E)) {
3179 if (
const auto *Exp = dyn_cast<ImplicitCastExpr>(E)) {
3184 if (
const auto *Exp = dyn_cast<CStyleCastExpr>(E)) {
3189 if (
const auto *Exp = dyn_cast<ObjCBridgedCastExpr>(E)) {
3194 if (
const auto *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
3196 if (LV.isObjCIvar() && !LV.isObjCArray())
3199 LV.setObjCIvar(
false);
3200 else if (LV.isGlobalObjCRef() && !LV.isObjCArray())
3203 LV.setGlobalObjCRef(
false);
3207 if (
const auto *Exp = dyn_cast<MemberExpr>(E)) {
3221 CGF, VD,
Addr, Loc);
3226 Addr =
Addr.withElementType(RealVarTy);
3232 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3233 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3237 if (!Res || ((*Res == OMPDeclareTargetDeclAttr::MT_To ||
3238 *Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
3241 assert(((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||
3242 ((*Res == OMPDeclareTargetDeclAttr::MT_To ||
3243 *Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
3245 "Expected link clause OR to clause with unified memory enabled.");
3255 llvm::LoadInst *Load =
3260 PTy, PointeeBaseInfo, PointeeTBAAInfo,
true);
3263 llvm::MDBuilder MDB(Ctx);
3265 if (
CGM.getTypes().getTargetAddressSpace(PTy) == 0 &&
3266 !
CGM.getCodeGenOpts().NullPointerIsValid)
3267 Load->setMetadata(llvm::LLVMContext::MD_nonnull,
3268 llvm::MDNode::get(Ctx, {}));
3274 llvm::LLVMContext::MD_align,
3275 llvm::MDNode::get(Ctx, MDB.createConstant(llvm::ConstantInt::get(
3276 Builder.getInt64Ty(), AlignVal))));
3281 true, PointeeBaseInfo,
3291 PointeeBaseInfo, PointeeTBAAInfo);
3301 BaseInfo, TBAAInfo);
3331 V = CGF.
Builder.CreateThreadLocalAddress(
V);
3339 VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
3354 if (FD->
hasAttr<WeakRefAttr>()) {
3369 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
V))
3370 V = llvm::NoCFIValue::get(GV);
3377 llvm::Value *ThisValue) {
3390 AsmLabelAttr *
Asm = VD->
getAttr<AsmLabelAttr>();
3391 assert(
Asm->getLabel().size() < 64-Name.size() &&
3392 "Register name too big");
3393 Name.append(
Asm->getLabel());
3394 llvm::NamedMDNode *M =
3395 CGM.
getModule().getOrInsertNamedMetadata(Name);
3396 if (M->getNumOperands() == 0) {
3399 llvm::Metadata *Ops[] = {Str};
3406 llvm::MetadataAsValue::get(CGM.
getLLVMContext(), M->getOperand(0));
3449 case llvm::GlobalValue::ExternalLinkage:
3450 case llvm::GlobalValue::LinkOnceODRLinkage:
3451 case llvm::GlobalValue::WeakODRLinkage:
3452 case llvm::GlobalValue::InternalLinkage:
3453 case llvm::GlobalValue::PrivateLinkage:
3465 "should not emit an unevaluated operand");
3467 if (
const auto *VD = dyn_cast<VarDecl>(ND)) {
3470 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
3478 (VD->getType()->isReferenceType() ||
3480 VD->getAnyInitializer(VD);
3482 E->
getLocation(), *VD->evaluateValue(), VD->getType());
3483 assert(Val &&
"failed to emit constant expression");
3486 if (!VD->getType()->isReferenceType()) {
3488 Addr =
CGM.createUnnamedGlobalFrom(*VD, Val,
3491 auto *PTy = llvm::PointerType::get(
3510 VD = VD->getCanonicalDecl();
3514 auto I = LocalDeclMap.find(VD);
3515 if (I != LocalDeclMap.end()) {
3517 if (VD->getType()->isReferenceType())
3525 CGM.getOpenMPRuntime().isNontemporalDecl(VD))
3542 CGM.getOpenMPRuntime().isNontemporalDecl(VD))
3558 "Should not use decl without marking it used!");
3560 if (ND->
hasAttr<WeakRefAttr>()) {
3566 if (
const auto *VD = dyn_cast<VarDecl>(ND)) {
3568 if (VD->hasLinkage() || VD->isStaticDataMember())
3574 auto iter = LocalDeclMap.find(VD);
3575 if (iter != LocalDeclMap.end()) {
3576 addr = iter->second;
3580 }
else if (VD->isStaticLocal()) {
3581 llvm::Constant *var =
CGM.getOrCreateStaticVarDecl(
3582 *VD,
CGM.getLLVMLinkageVarDefinition(VD));
3588 llvm_unreachable(
"DeclRefExpr for Decl not entered in LocalDeclMap?");
3599 VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
3606 bool isBlockByref = VD->isEscapingByref();
3612 LValue LV = VD->getType()->isReferenceType() ?
3616 bool isLocalStorage = VD->hasLocalStorage();
3618 bool NonGCable = isLocalStorage &&
3619 !VD->getType()->isReferenceType() &&
3626 bool isImpreciseLifetime =
3627 (isLocalStorage && !VD->hasAttr<ObjCPreciseLifetimeAttr>());
3628 if (isImpreciseLifetime)
3634 if (
const auto *FD = dyn_cast<FunctionDecl>(ND))
3640 if (
const auto *BD = dyn_cast<BindingDecl>(ND)) {
3657 if (
const auto *GD = dyn_cast<MSGuidDecl>(ND))
3661 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
3662 auto ATPO =
CGM.GetAddrOfTemplateParamObject(TPO);
3665 if (AS !=
T.getAddressSpace()) {
3667 auto PtrTy = llvm::PointerType::get(
CGM.getLLVMContext(), TargetAS);
3670 ATPO =
ConstantAddress(ASC, ATPO.getElementType(), ATPO.getAlignment());
3676 llvm_unreachable(
"Unhandled DeclRefExpr");
3686 default: llvm_unreachable(
"Unknown unary operator lvalue!");
3689 assert(!
T.isNull() &&
"CodeGenFunction::EmitUnaryOpLValue: Illegal type");
3711 assert(LV.
isSimple() &&
"real/imag on non-ordinary l-value");
3728 CGM.getTBAAInfoForSubobject(LV,
T));
3735 bool isInc = E->
getOpcode() == UO_PreInc;
3758 assert(SL !=
nullptr &&
"No StringLiteral name in PredefinedExpr");
3759 StringRef FnName =
CurFn->getName();
3760 FnName.consume_front(
"\01");
3761 StringRef NameItems[] = {
3763 std::string GVName = llvm::join(NameItems, NameItems + 2,
".");
3764 if (
auto *BD = dyn_cast_or_null<BlockDecl>(
CurCodeDecl)) {
3765 std::string Name = std::string(SL->getString());
3766 if (!Name.empty()) {
3767 unsigned Discriminator =
3768 CGM.getCXXABI().getMangleContext().getBlockId(BD,
true);
3770 Name +=
"_" + Twine(Discriminator + 1).str();
3771 auto C =
CGM.GetAddrOfConstantCString(Name, GVName);
3774 auto C =
CGM.GetAddrOfConstantCString(std::string(FnName), GVName);
3778 auto C =
CGM.GetAddrOfConstantStringFromLiteral(SL, GVName);
3795 if (llvm::Constant *
C =
CGM.getTypeDescriptorFromMap(
T))
3800 bool IsBitInt =
false;
3802 if (
T->isIntegerType()) {
3805 (
T->isSignedIntegerType() ? 1 : 0);
3809 if (
T->isSignedIntegerType() &&
T->getAs<
BitIntType>()) {
3812 " non positive amount of bits in __BitInt type");
3814 " too many bits in __BitInt type");
3821 }
else if (
T->isFloatingType()) {
3830 (
intptr_t)
T.getAsOpaquePtr(), StringRef(),
3831 StringRef(), {}, Buffer, {});
3836 char S[6] = {
'\0',
'\0',
'\0',
'\0',
'\0',
'\0'};
3839 llvm::support::endian::write32(S + 1, Bits,
3841 ? llvm::endianness::big
3842 : llvm::endianness::little);
3843 StringRef Str = StringRef(S,
sizeof(S) /
sizeof(
decltype(S[0])));
3847 llvm::Constant *Components[] = {
3851 llvm::Constant *Descriptor = llvm::ConstantStruct::getAnon(Components);
3853 auto *GV =
new llvm::GlobalVariable(
3854 CGM.getModule(), Descriptor->getType(),
3855 true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
3856 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
3857 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(GV);
3860 CGM.setTypeDescriptorInMap(
T, GV);
3868 if (
V->getType() == TargetTy)
3873 if (
V->getType()->isFloatingPointTy()) {
3874 unsigned Bits =
V->getType()->getPrimitiveSizeInBits().getFixedValue();
3875 if (Bits <= TargetTy->getIntegerBitWidth())
3881 if (
V->getType()->isIntegerTy() &&
3882 V->getType()->getIntegerBitWidth() <= TargetTy->getIntegerBitWidth())
3883 return Builder.CreateZExt(
V, TargetTy);
3886 if (!
V->getType()->isPointerTy()) {
3891 return Builder.CreatePtrToInt(
V, TargetTy);
3904 llvm::Constant *Filename;
3911 int PathComponentsToStrip =
3912 CGM.getCodeGenOpts().EmitCheckPathComponentsToStrip;
3913 if (PathComponentsToStrip < 0) {
3914 assert(PathComponentsToStrip !=
INT_MIN);
3915 int PathComponentsToKeep = -PathComponentsToStrip;
3916 auto I = llvm::sys::path::rbegin(FilenameString);
3917 auto E = llvm::sys::path::rend(FilenameString);
3918 while (I != E && --PathComponentsToKeep)
3921 FilenameString = FilenameString.substr(I - E);
3922 }
else if (PathComponentsToStrip > 0) {
3923 auto I = llvm::sys::path::begin(FilenameString);
3924 auto E = llvm::sys::path::end(FilenameString);
3925 while (I != E && PathComponentsToStrip--)
3930 FilenameString.substr(I - llvm::sys::path::begin(FilenameString));
3932 FilenameString = llvm::sys::path::filename(FilenameString);
3936 CGM.GetAddrOfConstantCString(std::string(FilenameString),
".src");
3937 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(
3939 FilenameGV.getPointer()->stripPointerCasts()));
3940 Filename = FilenameGV.getPointer();
3944 Filename = llvm::Constant::getNullValue(
Int8PtrTy);
3951 return llvm::ConstantStruct::getAnon(
Data);
3956enum class CheckRecoverableKind {
3967static CheckRecoverableKind
3969 if (Ordinal == SanitizerKind::SO_Vptr)
3970 return CheckRecoverableKind::AlwaysRecoverable;
3971 else if (Ordinal == SanitizerKind::SO_Return ||
3972 Ordinal == SanitizerKind::SO_Unreachable)
3973 return CheckRecoverableKind::Unrecoverable;
3975 return CheckRecoverableKind::Recoverable;
3979struct SanitizerHandlerInfo {
3980 char const *
const Name;
3986#define SANITIZER_CHECK(Enum, Name, Version, Msg) {#Name, Version},
3988#undef SANITIZER_CHECK
3992 llvm::FunctionType *FnType,
3995 CheckRecoverableKind RecoverKind,
bool IsFatal,
3996 llvm::BasicBlock *ContBB,
bool NoMerge) {
3997 assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
3998 std::optional<ApplyDebugLocation> DL;
3999 if (!CGF.
Builder.getCurrentDebugLocation()) {
4003 bool NeedsAbortSuffix =
4004 IsFatal && RecoverKind != CheckRecoverableKind::Unrecoverable;
4006 bool HandlerPreserveAllRegs =
4009 const StringRef CheckName = CheckInfo.Name;
4010 std::string FnName =
"__ubsan_handle_" + CheckName.str();
4011 if (CheckInfo.Version && !MinimalRuntime)
4012 FnName +=
"_v" + llvm::utostr(CheckInfo.Version);
4014 FnName +=
"_minimal";
4015 if (NeedsAbortSuffix)
4017 if (HandlerPreserveAllRegs && !NeedsAbortSuffix)
4018 FnName +=
"_preserve";
4020 !IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable;
4024 B.addAttribute(llvm::Attribute::NoReturn)
4025 .addAttribute(llvm::Attribute::NoUnwind);
4027 B.addUWTableAttr(llvm::UWTableKind::Default);
4032 llvm::AttributeList::FunctionIndex, B),
4038 HandlerCall->addFnAttr(llvm::Attribute::NoMerge);
4039 if (HandlerPreserveAllRegs && !NeedsAbortSuffix) {
4041 HandlerCall->setCallingConv(llvm::CallingConv::PreserveAll);
4044 HandlerCall->setDoesNotReturn();
4045 CGF.
Builder.CreateUnreachable();
4052 ArrayRef<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Checked,
4056 assert(Checked.size() > 0);
4057 assert(CheckHandler >= 0 &&
4061 llvm::Value *FatalCond =
nullptr;
4062 llvm::Value *RecoverableCond =
nullptr;
4063 llvm::Value *TrapCond =
nullptr;
4064 bool NoMerge =
false;
4071 for (
auto &[Check, Ord] : Checked) {
4072 llvm::Value *GuardedCheck = Check;
4074 (
CGM.getCodeGenOpts().SanitizeSkipHotCutoffs[Ord] > 0)) {
4076 CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check),
4077 llvm::ConstantInt::get(
CGM.Int8Ty, Ord));
4082 llvm::Value *&
Cond =
CGM.getCodeGenOpts().SanitizeTrap.has(Ord) ? TrapCond
4083 :
CGM.getCodeGenOpts().SanitizeRecover.has(Ord)
4088 if (!
CGM.getCodeGenOpts().SanitizeMergeHandlers.has(Ord))
4094 if (!FatalCond && !RecoverableCond)
4097 llvm::Value *JointCond;
4098 if (FatalCond && RecoverableCond)
4099 JointCond =
Builder.CreateAnd(FatalCond, RecoverableCond);
4101 JointCond = FatalCond ? FatalCond : RecoverableCond;
4105 assert(
SanOpts.has(Checked[0].second));
4107 for (
int i = 1, n = Checked.size(); i < n; ++i) {
4109 "All recoverable kinds in a single check must be same!");
4110 assert(
SanOpts.has(Checked[i].second));
4116 llvm::Instruction *Branch =
Builder.CreateCondBr(JointCond, Cont, Handlers);
4119 llvm::MDNode *Node = MDHelper.createLikelyBranchWeights();
4120 Branch->setMetadata(llvm::LLVMContext::MD_prof, Node);
4124 if (
CGM.getCodeGenOpts().SanitizeMinimalRuntime) {
4135 Args.reserve(DynamicArgs.size() + 1);
4136 ArgTypes.reserve(DynamicArgs.size() + 1);
4139 if (!StaticArgs.empty()) {
4140 llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
4141 auto *InfoPtr =
new llvm::GlobalVariable(
4142 CGM.getModule(), Info->getType(),
4145 false, llvm::GlobalVariable::PrivateLinkage, Info,
"",
4146 nullptr, llvm::GlobalVariable::NotThreadLocal,
4147 CGM.getDataLayout().getDefaultGlobalsAddressSpace());
4148 InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4149 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
4150 Args.push_back(InfoPtr);
4151 ArgTypes.push_back(Args.back()->getType());
4154 for (llvm::Value *DynamicArg : DynamicArgs) {
4159 llvm::FunctionType *FnType =
4160 llvm::FunctionType::get(
CGM.VoidTy, ArgTypes,
false);
4162 if (!FatalCond || !RecoverableCond) {
4166 (FatalCond !=
nullptr), Cont, NoMerge);
4170 llvm::BasicBlock *NonFatalHandlerBB =
4173 Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
4176 NonFatalHandlerBB, NoMerge);
4187 llvm::ConstantInt *TypeId, llvm::Value *Ptr,
4192 llvm::BranchInst *BI =
Builder.CreateCondBr(
Cond, Cont, CheckBB);
4195 llvm::MDNode *Node = MDHelper.createLikelyBranchWeights();
4196 BI->setMetadata(llvm::LLVMContext::MD_prof, Node);
4200 bool WithDiag = !
CGM.getCodeGenOpts().SanitizeTrap.has(Ordinal);
4202 llvm::CallInst *CheckCall;
4203 llvm::FunctionCallee SlowPathFn;
4205 llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
4207 new llvm::GlobalVariable(
CGM.getModule(), Info->getType(),
false,
4208 llvm::GlobalVariable::PrivateLinkage, Info);
4209 InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4210 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
4212 SlowPathFn =
CGM.getModule().getOrInsertFunction(
4213 "__cfi_slowpath_diag",
4216 CheckCall =
Builder.CreateCall(SlowPathFn, {TypeId, Ptr, InfoPtr});
4218 SlowPathFn =
CGM.getModule().getOrInsertFunction(
4221 CheckCall =
Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
4226 CheckCall->setDoesNotThrow();
4234 llvm::Module *M = &
CGM.getModule();
4236 QualType QInt64Ty =
C.getIntTypeForBitwidth(64,
false);
4243 FnArgs.push_back(&ArgCallsiteTypeId);
4244 FnArgs.push_back(&ArgAddr);
4245 FnArgs.push_back(&ArgCFICheckFailData);
4247 CGM.getTypes().arrangeBuiltinFunctionDeclaration(
C.VoidTy,
FnArgs);
4249 llvm::Function *F = llvm::Function::Create(
4251 llvm::GlobalValue::WeakAnyLinkage,
"__cfi_check", M);
4253 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
4254 F->setAlignment(llvm::Align(4096));
4257 llvm::LLVMContext &Ctx = M->getContext();
4258 llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx,
"entry", F);
4261 llvm::CallInst::Create(M->getFunction(
"__cfi_check_fail"), Args,
"", BB);
4262 llvm::ReturnInst::Create(Ctx,
nullptr, BB);
4273 auto CheckHandler = SanitizerHandler::CFICheckFail;
4280 {SanitizerKind::SO_CFIVCall, SanitizerKind::SO_CFINVCall,
4281 SanitizerKind::SO_CFIDerivedCast, SanitizerKind::SO_CFIUnrelatedCast,
4282 SanitizerKind::SO_CFIICall},
4289 Args.push_back(&ArgData);
4290 Args.push_back(&ArgAddr);
4295 llvm::Function *F = llvm::Function::Create(
4297 llvm::GlobalValue::WeakODRLinkage,
"__cfi_check_fail", &
CGM.getModule());
4300 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
4301 F->setVisibility(llvm::GlobalValue::HiddenVisibility);
4321 llvm::Value *DataIsNotNullPtr =
4326 EmitTrapCheck(DataIsNotNullPtr, SanitizerHandler::CFICheckFail,
4329 llvm::StructType *SourceLocationTy =
4331 llvm::StructType *CfiCheckFailDataTy =
4334 llvm::Value *
V =
Builder.CreateConstGEP2_32(
4338 llvm::Value *CheckKind =
Builder.CreateLoad(CheckKindAddr);
4340 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
4341 CGM.getLLVMContext(),
4342 llvm::MDString::get(
CGM.getLLVMContext(),
"all-vtables"));
4343 llvm::Value *ValidVtable =
Builder.CreateZExt(
4344 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::type_test),
4345 {Addr, AllVtables}),
4348 const std::pair<int, SanitizerKind::SanitizerOrdinal> CheckKinds[] = {
4355 for (
auto CheckKindOrdinalPair : CheckKinds) {
4356 int Kind = CheckKindOrdinalPair.first;
4363 Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(
Int8Ty, Kind));
4364 if (
CGM.getLangOpts().Sanitize.has(Ordinal))
4365 EmitCheck(std::make_pair(
Cond, Ordinal), SanitizerHandler::CFICheckFail,
4378 CGM.addUsedGlobal(F);
4382 if (
SanOpts.has(SanitizerKind::Unreachable)) {
4383 auto CheckOrdinal = SanitizerKind::SO_Unreachable;
4384 auto CheckHandler = SanitizerHandler::BuiltinUnreachable;
4400 if ((
int)TrapBBs.size() <= CheckHandlerID)
4401 TrapBBs.resize(CheckHandlerID + 1);
4403 llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
4405 llvm::DILocation *TrapLocation =
Builder.getCurrentDebugLocation();
4406 llvm::StringRef TrapMessage;
4407 llvm::StringRef TrapCategory;
4408 auto DebugTrapReasonKind =
CGM.getCodeGenOpts().getSanitizeDebugTrapReasons();
4410 DebugTrapReasonKind ==
4416 TrapCategory =
"Undefined Behavior Sanitizer";
4420 DebugTrapReasonKind !=
4424 TrapLocation, TrapCategory, TrapMessage);
4427 NoMerge = NoMerge || !
CGM.getCodeGenOpts().OptimizationLevel ||
4431 if (TrapBB && !NoMerge) {
4432 auto Call = TrapBB->begin();
4435 Call->applyMergedLocation(
Call->getDebugLoc(), TrapLocation);
4437 Builder.CreateCondBr(Checked, Cont, TrapBB,
4438 MDHelper.createLikelyBranchWeights());
4441 Builder.CreateCondBr(Checked, Cont, TrapBB,
4442 MDHelper.createLikelyBranchWeights());
4447 llvm::CallInst *TrapCall =
4448 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
4449 llvm::ConstantInt::get(
CGM.Int8Ty, CheckHandlerID));
4451 if (!
CGM.getCodeGenOpts().TrapFuncName.empty()) {
4452 auto A = llvm::Attribute::get(
getLLVMContext(),
"trap-func-name",
4453 CGM.getCodeGenOpts().TrapFuncName);
4454 TrapCall->addFnAttr(A);
4457 TrapCall->addFnAttr(llvm::Attribute::NoMerge);
4458 TrapCall->setDoesNotReturn();
4459 TrapCall->setDoesNotThrow();
4467 llvm::CallInst *TrapCall =
4468 Builder.CreateCall(
CGM.getIntrinsic(IntrID));
4470 if (!
CGM.getCodeGenOpts().TrapFuncName.empty()) {
4471 auto A = llvm::Attribute::get(
getLLVMContext(),
"trap-func-name",
4472 CGM.getCodeGenOpts().TrapFuncName);
4473 TrapCall->addFnAttr(A);
4477 TrapCall->addFnAttr(llvm::Attribute::NoMerge);
4485 "Array to pointer decay must have array source type!");
4494 Addr =
Addr.withElementType(NewTy);
4500 "Expected pointer to array");
4511 if (TBAAInfo) *TBAAInfo =
CGM.getTBAAAccessInfo(EltType);
4520 const auto *CE = dyn_cast<CastExpr>(E);
4521 if (!CE || CE->getCastKind() != CK_ArrayToPointerDecay)
4533 llvm::Type *elemType,
4539 const llvm::Twine &name =
"arrayidx") {
4551 llvm::Type *elementType,
bool inbounds,
4554 const llvm::Twine &name =
"arrayidx") {
4574 return D && D->
hasAttr<BPFPreserveStaticOffsetAttr>();
4581 if (PointeeType.
isNull())
4594 llvm::Function *Fn =
4596 llvm::CallInst *
Call = CGF.
Builder.CreateCall(Fn, {
Addr.emitRawPointer(CGF)});
4614 if (
const auto *ME = dyn_cast<MemberExpr>(E))
4615 return ME->getMemberDecl()->hasAttr<BPFPreserveAccessIndexAttr>();
4617 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
4618 const auto *VarDef = dyn_cast<VarDecl>(DRE->getDecl());
4622 const auto *PtrT = VarDef->getType()->getAs<
PointerType>();
4628 if (
const auto *RecT = dyn_cast<RecordType>(PointeeT))
4629 return RecT->getDecl()
4630 ->getMostRecentDecl()
4631 ->
hasAttr<BPFPreserveAccessIndexAttr>();
4644 const llvm::Twine &name =
"arrayidx") {
4647 for (
auto *idx : indices.drop_back())
4666 llvm::Value *eltPtr;
4667 auto LastIndex = dyn_cast<llvm::ConstantInt>(indices.back());
4672 signedIndices, loc, eltAlign, name);
4676 unsigned idx = LastIndex->getZExtValue();
4677 llvm::DIType *DbgInfo =
nullptr;
4680 eltPtr = CGF.
Builder.CreatePreserveArrayAccessIndex(
4692struct StructFieldAccess
4693 :
public ConstStmtVisitor<StructFieldAccess, const Expr *> {
4694 const Expr *VisitCastExpr(
const CastExpr *E) {
4699 const Expr *VisitParenExpr(
const ParenExpr *E) {
4708 const FieldDecl *Field, int64_t &Offset) {
4711 unsigned FieldNo = 0;
4746 if (FD1OuterRec != FD2OuterRec)
4748 return std::optional<int64_t>();
4750 int64_t FD1Offset = 0;
4752 return std::optional<int64_t>();
4754 int64_t FD2Offset = 0;
4756 return std::optional<int64_t>();
4758 return std::make_optional<int64_t>(FD1Offset - FD2Offset);
4770 QualType IndexType, llvm::Value *IndexVal,
bool Accessed,
4771 bool FlexibleArray) {
4772 const auto *ME = dyn_cast<MemberExpr>(ArrayExpr->
IgnoreImpCasts());
4773 if (!ME || !ME->getMemberDecl()->getType()->isCountAttributedType())
4778 if (FlexibleArray &&
4779 !ME->isFlexibleArrayMemberLike(
getContext(), StrictFlexArraysLevel))
4787 if (std::optional<int64_t> Diff =
4802 ArrayInst =
Builder.CreatePointerBitCastOrAddrSpaceCast(ArrayInst,
4806 llvm::Value *BoundsVal =
4808 Builder.getInt32(*Diff),
".counted_by.gep");
4810 ".counted_by.load");
4814 CountFD->
getType(), Accessed);
4822 llvm::Value *IdxPre =
4824 bool SignedIndices =
false;
4825 auto EmitIdxAfterBase = [&, IdxPre](
bool Promote) -> llvm::Value * {
4828 assert(E->
getRHS() == E->
getIdx() &&
"index was neither LHS nor RHS");
4834 SignedIndices |= IdxSigned;
4836 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4840 if (Promote && Idx->getType() !=
IntPtrTy)
4853 auto *Idx = EmitIdxAfterBase(
false);
4854 assert(LHS.
isSimple() &&
"Can only subscript lvalue vectors here!");
4862 std::optional<LValue> LV;
4865 LV =
CGM.getHLSLRuntime().emitResourceArraySubscriptExpr(E, *
this);
4867 LV =
CGM.getHLSLRuntime().emitBufferArraySubscriptExpr(E, *
this,
4879 auto *Idx = EmitIdxAfterBase(
true);
4886 CGM.getTBAAInfoForSubobject(LV, EltType));
4898 auto *Idx = EmitIdxAfterBase(
true);
4908 Idx =
Builder.CreateMul(Idx, numElements);
4910 Idx =
Builder.CreateNSWMul(Idx, numElements);
4922 auto *Idx = EmitIdxAfterBase(
true);
4925 llvm::Value *InterfaceSizeVal =
4926 llvm::ConstantInt::get(Idx->getType(), InterfaceSize.
getQuantity());
4928 llvm::Value *ScaledIdx =
Builder.CreateMul(Idx, InterfaceSizeVal);
4934 llvm::Type *OrigBaseElemTy =
Addr.getElementType();
4939 llvm::Value *EltPtr =
4941 ScaledIdx,
false, SignedIndices, E->
getExprLoc());
4948 assert(Array->getType()->isArrayType() &&
4949 "Array to pointer decay must have array source type!");
4953 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
4957 auto *Idx = EmitIdxAfterBase(
true);
4959 if (
SanOpts.has(SanitizerKind::ArrayBounds))
4967 *
this, ArrayLV.
getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
4971 if (!
CGM.getCodeGenOpts().NewStructPathTBAA) {
4974 EltTBAAInfo =
CGM.getTBAAInfoForSubobject(ArrayLV, E->
getType());
4979 EltTBAAInfo =
CGM.getTBAAAccessInfo(E->
getType());
5001 auto *Idx = EmitIdxAfterBase(
true);
5008 if (
SanOpts.has(SanitizerKind::ArrayBounds)) {
5009 StructFieldAccess Visitor;
5012 if (
const auto *CE = dyn_cast_if_present<CastExpr>(
Base);
5013 CE && CE->getCastKind() == CK_LValueToRValue)
5050 "incomplete matrix subscript expressions should be rejected during Sema");
5056 llvm::MatrixBuilder MB(
Builder);
5059 unsigned NumRows = MatrixTy->getNumRows();
5060 bool IsMatrixRowMajor =
getLangOpts().getDefaultMatrixMemoryLayout() ==
5062 llvm::Value *FinalIdx =
5063 MB.CreateIndex(RowIdx, ColIdx, NumRows, NumCols, IsMatrixRowMajor);
5074 bool IsLowerBound) {
5076 if (
auto *ASE = dyn_cast<ArraySectionExpr>(
Base->IgnoreParenImpCasts())) {
5080 BaseInfo = BaseLVal.getBaseInfo();
5085 Addr =
Addr.withElementType(NewTy);
5091 "Expected pointer to array");
5101 BaseInfo.mergeForCast(TypeBaseInfo);
5110 bool IsLowerBound) {
5113 "OpenACC Array section codegen not implemented");
5117 if (
auto *AT =
getContext().getAsArrayType(BaseTy))
5118 ResultExprTy = AT->getElementType();
5121 llvm::Value *Idx =
nullptr;
5129 LowerBound->getType()->hasSignedIntegerRepresentation());
5131 Idx = llvm::ConstantInt::getNullValue(
IntPtrTy);
5136 auto &
C =
CGM.getContext();
5138 llvm::APSInt ConstLength;
5141 if (std::optional<llvm::APSInt>
CL = Length->getIntegerConstantExpr(
C)) {
5148 if (std::optional<llvm::APSInt> LB =
5149 LowerBound->getIntegerConstantExpr(
C)) {
5151 LowerBound =
nullptr;
5156 else if (!LowerBound)
5159 if (Length || LowerBound) {
5160 auto *LowerBoundVal =
5164 LowerBound->getType()->hasSignedIntegerRepresentation())
5165 : llvm::ConstantInt::get(
IntPtrTy, ConstLowerBound);
5170 Length->getType()->hasSignedIntegerRepresentation())
5171 : llvm::ConstantInt::get(
IntPtrTy, ConstLength);
5172 Idx =
Builder.CreateAdd(LowerBoundVal, LengthVal,
"lb_add_len",
5175 if (Length && LowerBound) {
5177 Idx, llvm::ConstantInt::get(
IntPtrTy, 1),
"idx_sub_1",
5181 Idx = llvm::ConstantInt::get(
IntPtrTy, ConstLength + ConstLowerBound);
5187 if (
auto *VAT =
C.getAsVariableArrayType(ArrayTy)) {
5188 Length = VAT->getSizeExpr();
5189 if (std::optional<llvm::APSInt> L = Length->getIntegerConstantExpr(
C)) {
5194 auto *CAT =
C.getAsConstantArrayType(ArrayTy);
5195 assert(CAT &&
"unexpected type for array initializer");
5196 ConstLength = CAT->getSize();
5199 auto *LengthVal =
Builder.CreateIntCast(
5201 Length->getType()->hasSignedIntegerRepresentation());
5203 LengthVal, llvm::ConstantInt::get(
IntPtrTy, 1),
"len_sub_1",
5208 Idx = llvm::ConstantInt::get(
IntPtrTy, ConstLength);
5217 if (
auto *VLA =
getContext().getAsVariableArrayType(ResultExprTy)) {
5223 BaseTy, VLA->getElementType(), IsLowerBound);
5232 Idx =
Builder.CreateMul(Idx, NumElements);
5234 Idx =
Builder.CreateNSWMul(Idx, NumElements);
5243 assert(Array->getType()->isArrayType() &&
5244 "Array to pointer decay must have array source type!");
5248 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
5255 *
this, ArrayLV.
getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
5256 ResultExprTy, !
getLangOpts().PointerOverflowDefined,
5259 TBAAInfo =
CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
5263 ResultExprTy, IsLowerBound);
5286 Base.getQuals().removeObjCGCAttr();
5295 "Result must be a vector");
5303 if (LTy->getScalarSizeInBits() > Vec->getType()->getScalarSizeInBits())
5304 Vec =
Builder.CreateZExt(Vec, LTy);
5305 Builder.CreateStore(Vec, VecMem);
5316 if (
Base.isSimple()) {
5317 llvm::Constant *CV =
5322 if (
Base.isMatrixRow()) {
5324 llvm::dyn_cast<llvm::ConstantInt>(
Base.getMatrixRowIdx())) {
5330 MatIndices.reserve(NumCols);
5332 unsigned Row = RowIdx->getZExtValue();
5333 for (
unsigned C = 0;
C < NumCols; ++
C) {
5334 unsigned Col = Indices[
C];
5335 unsigned Linear = Col * NumRows + Row;
5336 MatIndices.push_back(llvm::ConstantInt::get(
Int32Ty, Linear));
5339 llvm::Constant *ConstIdxs = llvm::ConstantVector::get(MatIndices);
5344 llvm::Constant *Cols =
5351 Base.getMatrixAddress(),
Base.getMatrixRowIdx(), Cols,
Base.getType(),
5355 assert(
Base.isExtVectorElt() &&
"Can only subscript lvalue vec elts here!");
5357 llvm::Constant *BaseElts =
Base.getExtVectorElts();
5360 for (
unsigned Index : Indices)
5361 CElts.push_back(BaseElts->getAggregateElement(Index));
5362 llvm::Constant *CV = llvm::ConstantVector::get(CElts);
5369 while (
auto *BaseMemberExpr = dyn_cast<MemberExpr>(UnderlyingBaseExpr))
5370 UnderlyingBaseExpr = BaseMemberExpr->getBase()->
IgnoreParens();
5382 return CGM.getHLSLRuntime().emitBufferMemberExpr(*
this, E);
5389 bool IsInBounds = !
getLangOpts().PointerOverflowDefined &&
5401 SkippedChecks.
set(SanitizerKind::Alignment,
true);
5403 SkippedChecks.
set(SanitizerKind::Null,
true);
5411 if (
auto *Field = dyn_cast<FieldDecl>(ND)) {
5419 CGM.getOpenMPRuntime().isNontemporalDecl(Field)) ||
5426 if (
const auto *FD = dyn_cast<FunctionDecl>(ND))
5429 llvm_unreachable(
"Unhandled member declaration!");
5436 llvm::Value *ThisValue) {
5437 bool HasExplicitObjectParameter =
false;
5438 const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
CurCodeDecl);
5440 HasExplicitObjectParameter = MD->isExplicitObjectMemberFunction();
5441 assert(MD->getParent()->isLambda());
5442 assert(MD->getParent() == Field->getParent());
5445 if (HasExplicitObjectParameter) {
5447 auto It = LocalDeclMap.find(D);
5448 assert(It != LocalDeclMap.end() &&
"explicit parameter not loaded?");
5449 Address AddrOfExplicitObject = It->getSecond();
5460 if (ThisTy != LambdaTy) {
5463 LambdaLV.
getAddress(), ThisTy, BasePathArray.begin(),
5483 unsigned FieldIndex) {
5484 unsigned I = 0, Skipped = 0;
5487 if (I == FieldIndex)
5489 if (F->isUnnamedBitField())
5494 return FieldIndex - Skipped;
5504 if (Offset.isZero())
5517 const FieldDecl *field,
bool IsInBounds) {
5550 if (RD->isDynamicClass())
5553 for (
const auto &
Base : RD->bases())
5557 for (
const FieldDecl *Field : RD->fields())
5572 const bool UseVolatile =
isAAPCS(
CGM.getTarget()) &&
5573 CGM.getCodeGenOpts().AAPCSBitfieldWidth &&
5604 llvm::Type *FieldIntTy = llvm::Type::getIntNTy(
getLLVMContext(), SS);
5605 Addr =
Addr.withElementType(FieldIntTy);
5640 assert(!FieldTBAAInfo.
Offset &&
5641 "Nonzero offset for an access with no base type!");
5654 FieldTBAAInfo.
Size =
5661 if (
auto *ClassDef = dyn_cast<CXXRecordDecl>(rec)) {
5662 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
5663 ClassDef->isDynamicClass()) {
5677 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
5681 addr =
Builder.CreateLaunderInvariantGroup(addr);
5724 if (field->
hasAttr<AnnotateAttr>())
5740 QualType FieldType = Field->getType();
5746 *
this,
Base.getAddress(), Field,
5751 V =
V.withElementType(llvmType);
5760 CGM.getTBAAInfoForSubobject(
Base, FieldType));
5796 assert(E->
isTransparent() &&
"non-transparent glvalue init list");
5804 const Expr *Operand) {
5805 if (
auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Operand->IgnoreParens())) {
5807 return std::nullopt;
5816std::optional<LValue> HandleConditionalOperatorLValueSimpleCase(
5818 const Expr *condExpr = E->
getCond();
5823 std::swap(Live, Dead);
5833 if (
auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Live->
IgnoreParens())) {
5844 return std::nullopt;
5846struct ConditionalInfo {
5847 llvm::BasicBlock *lhsBlock, *rhsBlock;
5848 std::optional<LValue> LHS, RHS;
5853template<
typename FuncTy>
5855 const AbstractConditionalOperator *E,
5856 const FuncTy &BranchGenFunc) {
5872 Info.lhsBlock = CGF.
Builder.GetInsertBlock();
5875 CGF.
Builder.CreateBr(endBlock);
5883 Info.rhsBlock = CGF.
Builder.GetInsertBlock();
5895 "Unexpected conditional operator!");
5900 if (HandleConditionalOperatorLValueSimpleCase(*
this, E))
5903 EmitConditionalBlocks(*
this, E, [](CodeGenFunction &CGF,
const Expr *E) {
5910 if (!
expr->isGLValue()) {
5913 "Unexpected conditional operator!");
5918 if (std::optional<LValue> Res =
5919 HandleConditionalOperatorLValueSimpleCase(*
this,
expr))
5922 ConditionalInfo Info = EmitConditionalBlocks(
5923 *
this,
expr, [](CodeGenFunction &CGF,
const Expr *E) {
5927 if ((Info.LHS && !Info.LHS->isSimple()) ||
5928 (Info.RHS && !Info.RHS->isSimple()))
5931 if (Info.LHS && Info.RHS) {
5932 Address lhsAddr = Info.LHS->getAddress();
5933 Address rhsAddr = Info.RHS->getAddress();
5935 lhsAddr, rhsAddr, Info.lhsBlock, Info.rhsBlock,
5938 std::max(Info.LHS->getBaseInfo().getAlignmentSource(),
5939 Info.RHS->getBaseInfo().getAlignmentSource());
5941 Info.LHS->getTBAAInfo(), Info.RHS->getTBAAInfo());
5945 assert((Info.LHS || Info.RHS) &&
5946 "both operands of glvalue conditional are throw-expressions?");
5947 return Info.LHS ? *Info.LHS : *Info.RHS;
5959 llvm::scope_exit RestoreCurCast([
this, Prev =
CurCast] {
CurCast = Prev; });
5964 case CK_LValueToRValueBitCast:
5965 case CK_ArrayToPointerDecay:
5966 case CK_FunctionToPointerDecay:
5967 case CK_NullToMemberPointer:
5968 case CK_NullToPointer:
5969 case CK_IntegralToPointer:
5970 case CK_PointerToIntegral:
5971 case CK_PointerToBoolean:
5972 case CK_IntegralCast:
5973 case CK_BooleanToSignedIntegral:
5974 case CK_IntegralToBoolean:
5975 case CK_IntegralToFloating:
5976 case CK_FloatingToIntegral:
5977 case CK_FloatingToBoolean:
5978 case CK_FloatingCast:
5979 case CK_FloatingRealToComplex:
5980 case CK_FloatingComplexToReal:
5981 case CK_FloatingComplexToBoolean:
5982 case CK_FloatingComplexCast:
5983 case CK_FloatingComplexToIntegralComplex:
5984 case CK_IntegralRealToComplex:
5985 case CK_IntegralComplexToReal:
5986 case CK_IntegralComplexToBoolean:
5987 case CK_IntegralComplexCast:
5988 case CK_IntegralComplexToFloatingComplex:
5989 case CK_DerivedToBaseMemberPointer:
5990 case CK_BaseToDerivedMemberPointer:
5991 case CK_MemberPointerToBoolean:
5992 case CK_ReinterpretMemberPointer:
5993 case CK_AnyPointerToBlockPointerCast:
5994 case CK_ARCProduceObject:
5995 case CK_ARCConsumeObject:
5996 case CK_ARCReclaimReturnedObject:
5997 case CK_ARCExtendBlockObject:
5998 case CK_CopyAndAutoreleaseBlockObject:
5999 case CK_IntToOCLSampler:
6000 case CK_FloatingToFixedPoint:
6001 case CK_FixedPointToFloating:
6002 case CK_FixedPointCast:
6003 case CK_FixedPointToBoolean:
6004 case CK_FixedPointToIntegral:
6005 case CK_IntegralToFixedPoint:
6007 case CK_HLSLVectorTruncation:
6008 case CK_HLSLMatrixTruncation:
6009 case CK_HLSLArrayRValue:
6010 case CK_HLSLElementwiseCast:
6011 case CK_HLSLAggregateSplatCast:
6015 llvm_unreachable(
"dependent cast kind in IR gen!");
6017 case CK_BuiltinFnToFnPtr:
6018 llvm_unreachable(
"builtin functions are handled elsewhere");
6021 case CK_NonAtomicToAtomic:
6022 case CK_AtomicToNonAtomic:
6032 case CK_ConstructorConversion:
6033 case CK_UserDefinedConversion:
6034 case CK_CPointerToObjCPointerCast:
6035 case CK_BlockPointerToObjCPointerCast:
6036 case CK_LValueToRValue:
6051 if (
V.getElementType() !=
T)
6058 case CK_UncheckedDerivedToBase:
6059 case CK_DerivedToBase: {
6073 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6077 case CK_BaseToDerived: {
6092 if (
SanOpts.has(SanitizerKind::CFIDerivedCast))
6098 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6100 case CK_LValueBitCast: {
6104 CGM.EmitExplicitCastExprType(CE,
this);
6109 if (
SanOpts.has(SanitizerKind::CFIUnrelatedCast))
6115 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6117 case CK_AddressSpaceConversion: {
6127 case CK_ObjCObjectLValueCast: {
6131 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6133 case CK_ZeroToOCLOpaqueType:
6134 llvm_unreachable(
"NULL to OpenCL opaque type lvalue cast is not valid");
6136 case CK_VectorSplat: {
6144 llvm_unreachable(
"Unhandled lvalue cast kind?");
6152std::pair<LValue, LValue>
6167 return std::make_pair(BaseLV, TempLV);
6175 llvm::Value *
Addr = TempLV.getAddress().getBasePointer();
6180 Address TmpAddr(
Addr, ElTy, TempLV.getAlignment());
6190 llvm::DenseMap<const OpaqueValueExpr*,LValue>::iterator
6191 it = OpaqueLValues.find(e);
6193 if (it != OpaqueLValues.end())
6196 assert(e->
isUnique() &&
"LValue for a nonunique OVE hasn't been emitted");
6204 llvm::DenseMap<const OpaqueValueExpr*,RValue>::iterator
6205 it = OpaqueRValues.find(e);
6207 if (it != OpaqueRValues.end())
6210 assert(e->
isUnique() &&
"RValue for a nonunique OVE hasn't been emitted");
6216 return OpaqueLValues.contains(E);
6217 return OpaqueRValues.contains(E);
6241 llvm_unreachable(
"bad evaluation kind");
6250 llvm::CallBase **CallOrInvoke) {
6251 llvm::CallBase *CallOrInvokeStorage;
6252 if (!CallOrInvoke) {
6253 CallOrInvoke = &CallOrInvokeStorage;
6256 llvm::scope_exit AddCoroElideSafeOnExit([&] {
6258 auto *I = *CallOrInvoke;
6260 I->addFnAttr(llvm::Attribute::CoroElideSafe);
6268 if (
const auto *CE = dyn_cast<CXXMemberCallExpr>(E))
6271 if (
const auto *CE = dyn_cast<CUDAKernelCallExpr>(E))
6276 if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(E))
6277 if (
const auto *MD =
6278 dyn_cast_if_present<CXXMethodDecl>(CE->getCalleeDecl());
6279 MD && MD->isImplicitObjectMemberFunction())
6294 nullptr, CallOrInvoke);
6300 llvm::CallBase **CallOrInvoke) {
6303 nullptr, CallOrInvoke);
6311 if (!PD->isInlineBuiltinDeclaration())
6320 std::string NoBuiltinFD = (
"no-builtin-" + FD->
getName()).str();
6321 std::string NoBuiltins =
"no-builtins";
6324 std::string FDInlineName = (Ident +
".inline").str();
6326 bool IsPredefinedLibFunction =
6328 bool HasAttributeNoBuiltin =
6329 CGF.
CurFn->getAttributes().hasFnAttr(NoBuiltinFD) ||
6330 CGF.
CurFn->getAttributes().hasFnAttr(NoBuiltins);
6334 if (CGF.
CurFn->getName() != FDInlineName &&
6337 llvm::Function *Fn = llvm::cast<llvm::Function>(CalleePtr);
6338 llvm::Module *M = Fn->getParent();
6339 llvm::Function *Clone = M->getFunction(FDInlineName);
6341 Clone = llvm::Function::Create(Fn->getFunctionType(),
6342 llvm::GlobalValue::InternalLinkage,
6343 Fn->getAddressSpace(), FDInlineName, M);
6344 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
6355 else if (!IsPredefinedLibFunction || !HasAttributeNoBuiltin)
6361 FD->
hasAttr<CUDAGlobalAttr>())
6369 if (DeviceKernelAttr::isOpenCLSpelling(FD->
getAttr<DeviceKernelAttr>()))
6378 if (
auto ICE = dyn_cast<ImplicitCastExpr>(E)) {
6379 if (ICE->getCastKind() == CK_FunctionToPointerDecay ||
6380 ICE->getCastKind() == CK_BuiltinFnToFnPtr) {
6386 if (ICE->getCastKind() == CK_LValueToRValue) {
6387 const Expr *SubExpr = ICE->getSubExpr();
6389 std::pair<llvm::Value *, CGPointerAuthInfo>
Result =
6396 if (
const auto *VD =
6407 }
else if (
auto DRE = dyn_cast<DeclRefExpr>(E)) {
6408 if (
auto FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
6411 }
else if (
auto ME = dyn_cast<MemberExpr>(E)) {
6412 if (
auto FD = dyn_cast<FunctionDecl>(ME->getMemberDecl())) {
6418 }
else if (
auto NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
6422 }
else if (
auto PDE = dyn_cast<CXXPseudoDestructorExpr>(E)) {
6427 llvm::Value *calleePtr;
6439 if (
const auto *VD =
6445 CGCallee callee(calleeInfo, calleePtr, pointerAuth);
6461 assert(E->
getOpcode() == BO_Assign &&
"unexpected binary l-value");
6524 llvm::Value *
Result =
nullptr;
6527 if (
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
6542 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*
this,
6559 llvm_unreachable(
"bad evaluation kind");
6571 if (
CGM.getHLSLRuntime().emitResourceArrayCopy(LHS, E->
getRHS(), *
this))
6582 llvm::CallBase **CallOrInvoke) {
6590 "Can't have a scalar return unless the return type is a "
6603 &&
"binding l-value to type which needs a temporary");
6641 "Can't have a scalar return unless the return type is a "
6655 return CGM.getObjCRuntime().EmitIvarOffset(*
this,
Interface, Ivar);
6663 return Builder.CreateZExtOrTrunc(OffsetValue,
6668 llvm::Value *BaseValue,
6670 unsigned CVRQualifiers) {
6671 return CGM.getObjCRuntime().EmitObjCValueForIvar(*
this, ObjectTy, BaseValue,
6672 Ivar, CVRQualifiers);
6677 llvm::Value *BaseValue =
nullptr;
6688 ObjectTy = BaseExpr->
getType();
6710 llvm::CallBase **CallOrInvoke,
6715 "Call must have function pointer type!");
6717 const Decl *TargetDecl =
6720 assert((!isa_and_present<FunctionDecl>(TargetDecl) ||
6722 "trying to emit a call to an immediate function");
6732 if (
SanOpts.has(SanitizerKind::Function) &&
6735 if (llvm::Constant *PrefixSig =
6736 CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(
CGM)) {
6737 auto CheckOrdinal = SanitizerKind::SO_Function;
6738 auto CheckHandler = SanitizerHandler::FunctionTypeMismatch;
6742 llvm::Type *PrefixSigType = PrefixSig->getType();
6743 llvm::StructType *PrefixStructTy = llvm::StructType::get(
6744 CGM.getLLVMContext(), {PrefixSigType, Int32Ty},
true);
6746 llvm::Value *CalleePtr = Callee.getFunctionPointer();
6747 if (
CGM.getCodeGenOpts().PointerAuth.FunctionPointers) {
6750 Address(CalleePtr, CalleePtr->getType(),
6752 CalleePtr->getPointerAlignment(
CGM.getDataLayout())),
6753 Callee.getPointerAuthInfo(),
nullptr);
6754 CalleePtr =
Addr.emitRawPointer(*
this);
6766 llvm::Value *AlignedCalleePtr;
6767 if (
CGM.getTriple().isARM() ||
CGM.getTriple().isThumb()) {
6768 llvm::Value *CalleeAddress =
6770 llvm::Value *Mask = llvm::ConstantInt::getSigned(
IntPtrTy, ~1);
6771 llvm::Value *AlignedCalleeAddress =
6772 Builder.CreateAnd(CalleeAddress, Mask);
6774 Builder.CreateIntToPtr(AlignedCalleeAddress, CalleePtr->getType());
6776 AlignedCalleePtr = CalleePtr;
6779 llvm::Value *CalleePrefixStruct = AlignedCalleePtr;
6780 llvm::Value *CalleeSigPtr =
6781 Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 0);
6782 llvm::Value *CalleeSig =
6784 llvm::Value *CalleeSigMatch =
Builder.CreateICmpEQ(CalleeSig, PrefixSig);
6788 Builder.CreateCondBr(CalleeSigMatch, TypeCheck, Cont);
6791 llvm::Value *CalleeTypeHash =
Builder.CreateAlignedLoad(
6793 Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 1),
6795 llvm::Value *CalleeTypeHashMatch =
6796 Builder.CreateICmpEQ(CalleeTypeHash, TypeHash);
6799 EmitCheck(std::make_pair(CalleeTypeHashMatch, CheckOrdinal), CheckHandler,
6800 StaticData, {CalleePtr});
6809 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
6810 FD && DeviceKernelAttr::isOpenCLSpelling(FD->getAttr<DeviceKernelAttr>()))
6811 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FnType);
6815 if (
SanOpts.has(SanitizerKind::CFIICall) &&
6817 auto CheckOrdinal = SanitizerKind::SO_CFIICall;
6818 auto CheckHandler = SanitizerHandler::CFICheckFail;
6822 llvm::Metadata *MD =
6823 CGM.CreateMetadataIdentifierForFnType(
QualType(FnType, 0));
6825 llvm::Value *TypeId = llvm::MetadataAsValue::get(
getLLVMContext(), MD);
6827 llvm::Value *CalleePtr = Callee.getFunctionPointer();
6828 llvm::Value *TypeTest =
Builder.CreateCall(
6829 CGM.getIntrinsic(llvm::Intrinsic::type_test), {CalleePtr, TypeId});
6831 auto CrossDsoTypeId =
CGM.CreateCrossDsoCfiTypeId(MD);
6832 llvm::Constant *StaticData[] = {
6837 if (
CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
6841 EmitCheck(std::make_pair(TypeTest, CheckOrdinal), CheckHandler,
6842 StaticData, {CalleePtr, llvm::UndefValue::get(
IntPtrTy)});
6857 bool StaticOperator =
false;
6858 if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
6859 if (OCE->isAssignmentOp())
6862 switch (OCE->getOperator()) {
6864 case OO_GreaterGreater:
6876 if (
const auto *MD =
6877 dyn_cast_if_present<CXXMethodDecl>(OCE->getCalleeDecl());
6878 MD && MD->isStatic())
6879 StaticOperator =
true;
6883 if (StaticOperator) {
6887 Arguments = drop_begin(Arguments, 1);
6889 EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), Arguments,
6893 Args, FnType, Chain);
6896 *ResolvedFnInfo = &FnInfo;
6901 if (
CGM.getLangOpts().HIP && !
CGM.getLangOpts().CUDAIsDevice &&
6904 llvm::Value *Handle = Callee.getFunctionPointer();
6906 Address(Handle, Handle->getType(),
CGM.getPointerAlign()));
6907 Callee.setFunctionPointer(
Stub);
6909 llvm::CallBase *LocalCallOrInvoke =
nullptr;
6913 if (
auto *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
6914 if (CalleeDecl->hasAttr<RestrictAttr>() ||
6915 CalleeDecl->hasAttr<MallocSpanAttr>() ||
6916 CalleeDecl->hasAttr<AllocSizeAttr>()) {
6918 if (
SanOpts.has(SanitizerKind::AllocToken)) {
6925 *CallOrInvoke = LocalCallOrInvoke;
6944 bool IsInBounds = !
getLangOpts().PointerOverflowDefined &&
6947 E, BaseAddr, OffsetV, MPT, IsInBounds, &BaseInfo, &TBAAInfo);
6949 return MakeAddrLValue(MemberAddr, MPT->getPointeeType(), BaseInfo, TBAAInfo);
6966 llvm_unreachable(
"bad evaluation kind");
6970 assert(Val->getType()->isFPOrFPVectorTy());
6975 llvm::MDNode *Node = MDHelper.createFPMath(Accuracy);
6981 llvm::Type *EltTy = Val->getType()->getScalarType();
6982 if (!EltTy->isFloatTy())
6986 !
CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) ||
6988 !
CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) {
7002 llvm::Type *EltTy = Val->getType()->getScalarType();
7003 if (!EltTy->isFloatTy())
7007 !
CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) ||
7009 !
CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) {
7023 struct LValueOrRValue {
7037 LValueOrRValue result;
7041 const Expr *semantic = *i;
7045 if (
const auto *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
7047 if (ov->isUnique()) {
7048 assert(ov != resultExpr &&
7049 "A unique OVE cannot be used as the result expression");
7057 if (ov == resultExpr && ov->
isPRValue() && !forLValue &&
7062 opaqueData = OVMA::bind(CGF, ov, LV);
7067 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
7070 if (ov == resultExpr) {
7078 opaques.push_back(opaqueData);
7082 }
else if (semantic == resultExpr) {
7114 std::tuple<LValue, QualType, llvm::SmallVector<llvm::Value *, 4>>, 16>
7116 llvm::IntegerType *IdxTy = llvm::IntegerType::get(
getLLVMContext(), 32);
7117 WorkList.push_back({Val, Val.
getType(), {llvm::ConstantInt::get(IdxTy, 0)}});
7119 while (!WorkList.empty()) {
7120 auto [LVal,
T, IdxList] = WorkList.pop_back_val();
7121 T =
T.getCanonicalType().getUnqualifiedType();
7124 if (
const auto *CAT = dyn_cast<ConstantArrayType>(
T)) {
7125 uint64_t Size = CAT->getZExtSize();
7126 for (int64_t I = Size - 1; I > -1; I--) {
7128 IdxListCopy.push_back(llvm::ConstantInt::get(IdxTy, I));
7129 WorkList.emplace_back(LVal, CAT->getElementType(), IdxListCopy);
7131 }
else if (
const auto *RT = dyn_cast<RecordType>(
T)) {
7133 assert(!
Record->isUnion() &&
"Union types not supported in flat cast.");
7138 std::tuple<LValue, QualType, llvm::SmallVector<llvm::Value *, 4>>, 16>
7147 "HLSL doesn't support multiple inheritance.");
7150 IdxListCopy.push_back(llvm::ConstantInt::get(
7152 ReverseList.emplace_back(LVal,
Base->getType(), IdxListCopy);
7161 bool createdGEP =
false;
7162 for (
auto *FD :
Record->fields()) {
7163 if (FD->isBitField()) {
7164 if (FD->isUnnamedBitField())
7168 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList,
7169 LLVMT, Align,
"gep");
7173 ReverseList.push_back({FieldLVal, FD->
getType(), {}});
7176 IdxListCopy.push_back(
7178 ReverseList.emplace_back(LVal, FD->getType(), IdxListCopy);
7182 std::reverse(ReverseList.begin(), ReverseList.end());
7183 llvm::append_range(WorkList, ReverseList);
7184 }
else if (
const auto *VT = dyn_cast<VectorType>(
T)) {
7187 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList, LLVMT,
7188 Align,
"vector.gep");
7190 for (
unsigned I = 0, E = VT->getNumElements(); I < E; I++) {
7191 llvm::Constant *Idx = llvm::ConstantInt::get(IdxTy, I);
7195 AccessList.emplace_back(LV);
7198 if (!IdxList.empty()) {
7201 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList,
7202 LLVMT, Align,
"gep");
7205 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.
@ UseSkipPath
Skip (false)
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...
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
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
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)
llvm::Constant * getMatrixRowElts() const
bool isObjCStrong() const
bool isMatrixRowSwizzle() 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)
static LValue MakeMatrixRowSwizzle(Address MatAddr, llvm::Value *RowIdx, llvm::Constant *Cols, QualType MatrixTy, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
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 isConstantMatrixBoolType() 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