44#include "llvm/ADT/STLExtras.h"
45#include "llvm/ADT/ScopeExit.h"
46#include "llvm/ADT/StringExtras.h"
47#include "llvm/IR/Constants.h"
48#include "llvm/IR/DataLayout.h"
49#include "llvm/IR/Intrinsics.h"
50#include "llvm/IR/IntrinsicsWebAssembly.h"
51#include "llvm/IR/LLVMContext.h"
52#include "llvm/IR/MDBuilder.h"
53#include "llvm/IR/MatrixBuilder.h"
54#include "llvm/Support/ConvertUTF.h"
55#include "llvm/Support/Endian.h"
56#include "llvm/Support/MathExtras.h"
57#include "llvm/Support/Path.h"
58#include "llvm/Support/xxhash.h"
59#include "llvm/Transforms/Utils/SanitizerStats.h"
73 llvm::cl::desc(
"Guard UBSAN checks with `llvm.allow.ubsan.check()`."));
99#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
100 case SanitizerHandler::Enum: \
103#undef SANITIZER_CHECK
105 llvm_unreachable(
"unhandled switch case");
113 llvm::Value *ArraySize) {
115 auto Alloca =
Builder.CreateStructuredAlloca(Ty, Name);
126 llvm::Value *ArraySize) {
136 llvm::IRBuilderBase::InsertPointGuard IPG(Builder);
151 llvm::Value *ArraySize,
155 *AllocaAddr = Alloca;
156 return MaybeCastStackAddressSpace(Alloca, DestLangAS, ArraySize);
164 llvm::Value *ArraySize) {
165 llvm::AllocaInst *Alloca;
167 Alloca =
Builder.CreateAlloca(Ty, ArraySize, Name);
170 new llvm::AllocaInst(Ty,
CGM.getDataLayout().getAllocaAddrSpace(),
172 if (
SanOpts.Mask & SanitizerKind::Address) {
173 Alloca->addAnnotationMetadata({
"alloca_name_altered", Name.str()});
176 Allocas->Add(Alloca);
213 auto *ArrayElementTy = ArrayTy->getElementType();
214 auto ArrayElements = ArrayTy->getNumElements();
217 ArrayElementTy = VectorTy->getElementType();
218 ArrayElements *= VectorTy->getNumElements();
220 auto *VectorTy = llvm::FixedVectorType::get(ArrayElementTy, ArrayElements);
243 PGO->setCurrentStmt(E);
246 return CGM.getCXXABI().EmitMemberPointerIsNotNull(*
this, MemPtr, MPT);
269 if (
const auto *CondOp = dyn_cast<AbstractConditionalOperator>(
292 if (!ignoreResult && aggSlot.
isIgnored())
297 llvm_unreachable(
"bad evaluation kind");
339 llvm_unreachable(
"bad evaluation kind");
362 llvm_unreachable(
"bad evaluation kind");
402 bool Precise = isa_and_nonnull<VarDecl>(VD) &&
403 VD->
hasAttr<ObjCPreciseLifetimeAttr>();
424 llvm_unreachable(
"temporary cannot have dynamic storage duration");
426 llvm_unreachable(
"unknown storage duration");
436 if (
const auto *ClassDecl =
440 ReferenceTemporaryDtor = ClassDecl->getDestructor();
442 if (!ReferenceTemporaryDtor)
447 bool CanRegisterDestructor =
452 llvm::FunctionCallee CleanupFn;
453 llvm::Constant *CleanupArg;
459 CleanupArg = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
476 llvm_unreachable(
"temporary cannot have dynamic storage duration");
498 auto *GV =
new llvm::GlobalVariable(
500 llvm::GlobalValue::PrivateLinkage,
Init,
".ref.tmp",
nullptr,
501 llvm::GlobalValue::NotThreadLocal,
505 llvm::Constant *
C = GV;
512 return RawAddress(
C, GV->getValueType(), alignment);
521 llvm_unreachable(
"temporary can't have dynamic storage duration");
523 llvm_unreachable(
"unknown storage duration");
532 "Reference should never be pseudo-strong!");
540 if (
auto *Var = dyn_cast<llvm::GlobalVariable>(
Object.getPointer())) {
550 if (Var->hasInitializer())
553 Var->setInitializer(
CGM.EmitNullConstant(E->
getType()));
559 default: llvm_unreachable(
"expected scalar or aggregate expression");
582 for (
const auto &Ignored : CommaLHSs)
585 if (
const auto *opaque = dyn_cast<OpaqueValueExpr>(E)) {
586 if (opaque->getType()->isRecordType()) {
587 assert(Adjustments.empty());
595 if (
auto *Var = dyn_cast<llvm::GlobalVariable>(
596 Object.getPointer()->stripPointerCasts())) {
602 if (!Var->hasInitializer()) {
603 Var->setInitializer(
CGM.EmitNullConstant(E->
getType()));
624 if (!ShouldEmitLifetimeMarkers)
635 CGBuilderTy::InsertPoint OldIP;
637 ((!
SanOpts.has(SanitizerKind::HWAddress) &&
638 !
SanOpts.has(SanitizerKind::Memory) &&
639 !
SanOpts.has(SanitizerKind::MemtagStack) &&
640 !
CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) ||
642 OldConditional = OutermostConditional;
643 OutermostConditional =
nullptr;
654 if (OldConditional) {
655 OutermostConditional = OldConditional;
672 switch (Adjustment.Kind) {
676 Adjustment.DerivedToBase.BasePath->path_begin(),
677 Adjustment.DerivedToBase.BasePath->path_end(),
685 "materialized temporary field is not a simple lvalue");
693 E,
Object, Ptr, Adjustment.Ptr.MPT,
true);
726 const llvm::Constant *Elts) {
734 Builder.CreateMul(Ptr, Builder.getInt64(0xbf58476d1ce4e5b9u));
736 Builder.CreateXor(A0, Builder.CreateLShr(A0, Builder.getInt64(31)));
737 return Builder.CreateXor(Acc, A1);
754 return SanOpts.has(SanitizerKind::Null) ||
755 SanOpts.has(SanitizerKind::Alignment) ||
756 SanOpts.has(SanitizerKind::ObjectSize) ||
757 SanOpts.has(SanitizerKind::Vptr);
764 llvm::Value *ArraySize) {
771 if (Ptr->getType()->getPointerAddressSpace())
782 auto PtrToAlloca = dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCasts());
784 llvm::Value *IsNonNull =
nullptr;
785 bool IsGuaranteedNonNull =
786 SkippedChecks.
has(SanitizerKind::Null) || PtrToAlloca;
788 llvm::BasicBlock *Done =
nullptr;
789 bool DoneViaNullSanitize =
false;
792 auto CheckHandler = SanitizerHandler::TypeMismatch;
794 {SanitizerKind::SO_Null,
795 SanitizerKind::SO_ObjectSize,
796 SanitizerKind::SO_Alignment},
804 if ((
SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
805 !IsGuaranteedNonNull) {
807 IsNonNull =
Builder.CreateIsNotNull(Ptr);
811 IsGuaranteedNonNull = IsNonNull ==
True;
814 if (!IsGuaranteedNonNull) {
815 if (AllowNullPointers) {
819 DoneViaNullSanitize =
true;
821 Builder.CreateCondBr(IsNonNull, Rest, Done);
824 Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null));
829 if (
SanOpts.has(SanitizerKind::ObjectSize) &&
830 !SkippedChecks.
has(SanitizerKind::ObjectSize) &&
832 uint64_t TySize =
CGM.getMinimumObjectSize(Ty).getQuantity();
833 llvm::Value *Size = llvm::ConstantInt::get(
IntPtrTy, TySize);
835 Size =
Builder.CreateMul(Size, ArraySize);
838 llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
839 if (!ConstantSize || !ConstantSize->isNullValue()) {
846 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
848 llvm::Value *NullIsUnknown =
Builder.getFalse();
849 llvm::Value *Dynamic =
Builder.getFalse();
850 llvm::Value *LargeEnough =
Builder.CreateICmpUGE(
851 Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
853 std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize));
857 llvm::MaybeAlign AlignVal;
858 llvm::Value *PtrAsInt =
nullptr;
860 if (
SanOpts.has(SanitizerKind::Alignment) &&
861 !SkippedChecks.
has(SanitizerKind::Alignment)) {
864 AlignVal =
CGM.getNaturalTypeAlignment(Ty,
nullptr,
nullptr,
869 if (AlignVal && *AlignVal > llvm::Align(1) &&
870 (!PtrToAlloca || PtrToAlloca->getAlign() < *AlignVal)) {
872 llvm::Value *Align =
Builder.CreateAnd(
873 PtrAsInt, llvm::ConstantInt::get(
IntPtrTy, AlignVal->value() - 1));
874 llvm::Value *Aligned =
878 std::make_pair(Aligned, SanitizerKind::SO_Alignment));
882 if (Checks.size() > 0) {
883 llvm::Constant *StaticData[] = {
885 llvm::ConstantInt::get(
Int8Ty, AlignVal ? llvm::Log2(*AlignVal) : 1),
886 llvm::ConstantInt::get(
Int8Ty, TCK)};
887 EmitCheck(Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr);
899 if (
SanOpts.has(SanitizerKind::Vptr) &&
902 SanitizerHandler::DynamicTypeCacheMiss);
906 if (!IsGuaranteedNonNull) {
908 IsNonNull =
Builder.CreateIsNotNull(Ptr);
912 Builder.CreateCondBr(IsNonNull, VptrNotNull, Done);
918 llvm::raw_svector_ostream Out(MangledName);
923 if (!
CGM.getContext().getNoSanitizeList().containsType(SanitizerKind::Vptr,
926 llvm::Value *TypeHash =
927 llvm::ConstantInt::get(
Int64Ty, xxh3_64bits(Out.str()));
941 const int CacheSize = 128;
942 llvm::Type *HashTable = llvm::ArrayType::get(
IntPtrTy, CacheSize);
943 llvm::Value *
Cache =
CGM.CreateRuntimeVariable(HashTable,
944 "__ubsan_vptr_type_cache");
945 llvm::Value *Slot =
Builder.CreateAnd(Hash,
948 llvm::Value *Indices[] = {
Builder.getInt32(0), Slot };
949 llvm::Value *CacheVal =
Builder.CreateAlignedLoad(
957 llvm::Value *EqualHash =
Builder.CreateICmpEQ(CacheVal, Hash);
958 llvm::Constant *StaticData[] = {
962 llvm::ConstantInt::get(
Int8Ty, TCK)
964 llvm::Value *DynamicData[] = { Ptr, Hash };
965 EmitCheck(std::make_pair(EqualHash, SanitizerKind::SO_Vptr),
966 SanitizerHandler::DynamicTypeCacheMiss, StaticData,
974 {DoneViaNullSanitize ? SanitizerKind::SO_Null : SanitizerKind::SO_Vptr},
975 DoneViaNullSanitize ? SanitizerHandler::TypeMismatch
976 : SanitizerHandler::DynamicTypeCacheMiss);
985 uint64_t EltSize =
C.getTypeSizeInChars(EltTy).getQuantity();
993 auto *ParamDecl = dyn_cast<ParmVarDecl>(ArrayDeclRef->getDecl());
997 auto *POSAttr = ParamDecl->getAttr<PassObjectSizeAttr>();
1002 int POSType = POSAttr->getType();
1003 if (POSType != 0 && POSType != 1)
1007 auto PassedSizeIt = SizeArguments.find(ParamDecl);
1008 if (PassedSizeIt == SizeArguments.end())
1012 assert(LocalDeclMap.count(PassedSizeDecl) &&
"Passed size not loadable");
1013 Address AddrOfSize = LocalDeclMap.find(PassedSizeDecl)->second;
1016 llvm::Value *SizeOfElement =
1017 llvm::ConstantInt::get(SizeInBytes->getType(), EltSize);
1018 return Builder.CreateUDiv(SizeInBytes, SizeOfElement);
1027 StrictFlexArraysLevel) {
1030 IndexedType =
Base->getType();
1031 return CGF.
Builder.getInt32(VT->getNumElements());
1036 if (
const auto *CE = dyn_cast<CastExpr>(
Base)) {
1037 if (CE->getCastKind() == CK_ArrayToPointerDecay &&
1038 !CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.
getContext(),
1039 StrictFlexArraysLevel)) {
1042 IndexedType = CE->getSubExpr()->getType();
1044 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
1045 return CGF.
Builder.getInt(CAT->getSize());
1047 if (
const auto *VAT = dyn_cast<VariableArrayType>(AT))
1055 QualType EltTy{
Base->getType()->getPointeeOrArrayElementType(), 0};
1057 IndexedType =
Base->getType();
1098class StructAccessBase
1099 :
public ConstStmtVisitor<StructAccessBase, const Expr *> {
1103 const FieldDecl *CountDecl;
1108 bool IsExpectedRecordDecl(
const Expr *E)
const {
1117 StructAccessBase(
const FieldDecl *CountDecl) : CountDecl(CountDecl) {}
1136 const Expr *Visit(
const Expr *E) {
1137 return ConstStmtVisitor<StructAccessBase, const Expr *>::Visit(E);
1140 const Expr *VisitStmt(
const Stmt *S) {
return nullptr; }
1155 const Expr *VisitDeclRefExpr(
const DeclRefExpr *E) {
1156 return IsExpectedRecordDecl(E) ? E :
nullptr;
1158 const Expr *VisitMemberExpr(
const MemberExpr *E) {
1159 if (IsExpectedRecordDecl(E) && E->
isArrow())
1161 const Expr *Res = Visit(E->
getBase());
1162 return !Res && IsExpectedRecordDecl(E) ? E : Res;
1164 const Expr *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
1165 return IsExpectedRecordDecl(E) ? E :
nullptr;
1167 const Expr *VisitCallExpr(
const CallExpr *E) {
1168 return IsExpectedRecordDecl(E) ? E :
nullptr;
1171 const Expr *VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
1172 if (IsExpectedRecordDecl(E))
1176 const Expr *VisitCastExpr(
const CastExpr *E) {
1178 return IsExpectedRecordDecl(E) ? E :
nullptr;
1181 const Expr *VisitParenExpr(
const ParenExpr *E) {
1184 const Expr *VisitUnaryAddrOf(
const UnaryOperator *E) {
1187 const Expr *VisitUnaryDeref(
const UnaryOperator *E) {
1200 int64_t FieldNo = -1;
1209 Indices.emplace_back(CGF.
Builder.getInt32(FieldNo));
1218 Indices.emplace_back(CGF.
Builder.getInt32(FieldNo));
1234 const Expr *StructBase = StructAccessBase(CountDecl).Visit(
Base);
1246 llvm::Value *Res =
nullptr;
1251 Res =
Addr.emitRawPointer(*
this);
1252 }
else if (StructBase->
isLValue()) {
1255 Res =
Addr.emitRawPointer(*
this);
1262 if (Indices.empty())
1265 Indices.push_back(
Builder.getInt32(0));
1289 const Expr *ArrayExprBase,
1290 llvm::Value *IndexVal,
QualType IndexType,
1292 assert(
SanOpts.has(SanitizerKind::ArrayBounds) &&
1293 "should not be called unless adding bounds checks");
1298 *
this, ArrayExprBase, ArrayExprBaseType, StrictFlexArraysLevel);
1301 BoundsVal,
getContext().getSizeType(), Accessed);
1306 llvm::Value *IndexVal,
1308 llvm::Value *BoundsVal,
1309 QualType BoundsType,
bool Accessed) {
1313 auto CheckKind = SanitizerKind::SO_ArrayBounds;
1314 auto CheckHandler = SanitizerHandler::OutOfBounds;
1326 llvm::Value *IndexInst =
Builder.CreateIntCast(IndexVal, Ty, IndexSigned);
1327 llvm::Value *BoundsInst =
Builder.CreateIntCast(BoundsVal, Ty,
false);
1329 llvm::Constant *StaticData[] = {
1335 llvm::Value *Check = Accessed ?
Builder.CreateICmpULT(IndexInst, BoundsInst)
1336 :
Builder.CreateICmpULE(IndexInst, BoundsInst);
1341 BoundsVal, llvm::ConstantInt::get(BoundsVal->getType(), 0));
1345 EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData,
1355 auto *TypeNameMD = MDB.createString(ATMD->TypeName);
1356 auto *ContainsPtrC =
Builder.getInt1(ATMD->ContainsPointer);
1357 auto *ContainsPtrMD = MDB.createConstant(ContainsPtrC);
1360 return llvm::MDNode::get(
CGM.getLLVMContext(), {TypeNameMD, ContainsPtrMD});
1364 assert(
SanOpts.has(SanitizerKind::AllocToken) &&
1365 "Only needed with -fsanitize=alloc-token");
1366 CB->setMetadata(llvm::LLVMContext::MD_alloc_token,
1378 assert(
SanOpts.has(SanitizerKind::AllocToken) &&
1379 "Only needed with -fsanitize=alloc-token");
1381 CB->setMetadata(llvm::LLVMContext::MD_alloc_token, MDN);
1386 bool isInc,
bool isPre) {
1389 llvm::Value *NextVal;
1391 uint64_t AmountVal = isInc ? 1 : -1;
1392 NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal,
true);
1395 NextVal =
Builder.CreateAdd(InVal.first, NextVal, isInc ?
"inc" :
"dec");
1398 llvm::APFloat FVal(
getContext().getFloatTypeSemantics(ElemTy), 1);
1404 NextVal =
Builder.CreateFAdd(InVal.first, NextVal, isInc ?
"inc" :
"dec");
1412 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*
this,
1417 return isPre ? IncVal : InVal;
1427 DI->EmitExplicitCastType(E->
getType());
1438 if (
auto *constantIdx = dyn_cast<llvm::ConstantInt>(idx)) {
1439 CharUnits offset = constantIdx->getZExtValue() * eltSize;
1453 assert(BO->
isAdditiveOp() &&
"Expect an addition or subtraction.");
1456 bool isSubtraction = BO->
getOpcode() == BO_Sub;
1459 llvm::Value *
index =
nullptr;
1463 std::swap(pointerOperand, indexOperand);
1475 BO, pointerOperand, pointer, indexOperand,
index, isSubtraction);
1482 nullptr, IsKnownNonNull);
1495 if (
const CastExpr *CE = dyn_cast<CastExpr>(E)) {
1496 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(CE))
1499 switch (CE->getCastKind()) {
1503 case CK_AddressSpaceConversion:
1504 if (
auto PtrTy = CE->getSubExpr()->getType()->getAs<
PointerType>()) {
1505 if (PtrTy->getPointeeType()->isVoidType())
1511 CE->getSubExpr(), &InnerBaseInfo, &InnerTBAAInfo, IsKnownNonNull);
1512 if (BaseInfo) *BaseInfo = InnerBaseInfo;
1513 if (TBAAInfo) *TBAAInfo = InnerTBAAInfo;
1519 E->
getType(), &TargetTypeBaseInfo, &TargetTypeTBAAInfo);
1527 BaseInfo->mergeForCast(TargetTypeBaseInfo);
1528 Addr.setAlignment(Align);
1532 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast) &&
1533 CE->getCastKind() == CK_BitCast) {
1541 llvm::Type *ElemTy =
1543 Addr =
Addr.withElementType(ElemTy);
1544 if (CE->getCastKind() == CK_AddressSpaceConversion)
1554 case CK_ArrayToPointerDecay:
1558 case CK_UncheckedDerivedToBase:
1559 case CK_DerivedToBase: {
1566 CE->getSubExpr(), BaseInfo,
nullptr,
1568 CE->getCastKind() == CK_UncheckedDerivedToBase));
1569 auto Derived = CE->getSubExpr()->
getType()->getPointeeCXXRecordDecl();
1571 Addr, Derived, CE->path_begin(), CE->path_end(),
1584 if (UO->getOpcode() == UO_AddrOf) {
1585 LValue LV = CGF.
EmitLValue(UO->getSubExpr(), IsKnownNonNull);
1586 if (BaseInfo) *BaseInfo = LV.getBaseInfo();
1587 if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
1588 return LV.getAddress();
1593 if (
auto *
Call = dyn_cast<CallExpr>(E)) {
1594 switch (
Call->getBuiltinCallee()) {
1597 case Builtin::BIaddressof:
1598 case Builtin::BI__addressof:
1599 case Builtin::BI__builtin_addressof: {
1601 if (BaseInfo) *BaseInfo = LV.getBaseInfo();
1602 if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
1603 return LV.getAddress();
1609 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
1610 if (BO->isAdditiveOp())
1619 true, BaseInfo, TBAAInfo, IsKnownNonNull);
1629 if (IsKnownNonNull && !
Addr.isKnownNonNull())
1630 Addr.setKnownNonNull();
1637 return CGM.getCXXABI().EmitMemberPointerIsNotNull(*
this,
V, MPT);
1638 return Builder.CreateICmpNE(
V, llvm::Constant::getNullValue(
V->getType()));
1649 llvm::Value *
U = llvm::UndefValue::get(EltTy);
1664 llvm_unreachable(
"bad evaluation kind");
1689 if (
const auto *CE = dyn_cast<CastExpr>(
Base)) {
1690 Base = CE->getSubExpr();
1691 }
else if (
const auto *PE = dyn_cast<ParenExpr>(
Base)) {
1692 Base = PE->getSubExpr();
1693 }
else if (
const auto *UO = dyn_cast<UnaryOperator>(
Base)) {
1694 if (UO->getOpcode() == UO_Extension)
1695 Base = UO->getSubExpr();
1713 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
1716 SkippedChecks.
set(SanitizerKind::Alignment,
true);
1718 SkippedChecks.
set(SanitizerKind::Null,
true);
1745 CGM.runWithSufficientStackSpace(
1746 E->
getExprLoc(), [&] { LV = EmitLValueHelper(E, IsKnownNonNull); });
1753LValue CodeGenFunction::EmitLValueHelper(
const Expr *E,
1759 case Expr::ObjCPropertyRefExprClass:
1760 llvm_unreachable(
"cannot emit a property reference directly");
1762 case Expr::ObjCSelectorExprClass:
1764 case Expr::ObjCIsaExprClass:
1766 case Expr::BinaryOperatorClass:
1768 case Expr::CompoundAssignOperatorClass: {
1771 Ty = AT->getValueType();
1776 case Expr::CallExprClass:
1777 case Expr::CXXMemberCallExprClass:
1778 case Expr::CXXOperatorCallExprClass:
1779 case Expr::UserDefinedLiteralClass:
1781 case Expr::CXXRewrittenBinaryOperatorClass:
1784 case Expr::VAArgExprClass:
1786 case Expr::DeclRefExprClass:
1788 case Expr::ConstantExprClass: {
1794 case Expr::ParenExprClass:
1796 case Expr::GenericSelectionExprClass:
1799 case Expr::PredefinedExprClass:
1801 case Expr::StringLiteralClass:
1803 case Expr::ObjCEncodeExprClass:
1805 case Expr::PseudoObjectExprClass:
1807 case Expr::InitListExprClass:
1809 case Expr::CXXTemporaryObjectExprClass:
1810 case Expr::CXXConstructExprClass:
1812 case Expr::CXXBindTemporaryExprClass:
1814 case Expr::CXXUuidofExprClass:
1816 case Expr::LambdaExprClass:
1819 case Expr::ExprWithCleanupsClass: {
1821 RunCleanupsScope
Scope(*
this);
1822 LValue LV =
EmitLValue(cleanups->getSubExpr(), IsKnownNonNull);
1823 if (LV.isSimple()) {
1827 llvm::Value *
V =
Addr.getBasePointer();
1828 Scope.ForceCleanup({&
V});
1829 Addr.replaceBasePointer(
V);
1831 LV.getBaseInfo(), LV.getTBAAInfo());
1838 case Expr::CXXDefaultArgExprClass: {
1841 return EmitLValue(DAE->getExpr(), IsKnownNonNull);
1843 case Expr::CXXDefaultInitExprClass: {
1846 return EmitLValue(DIE->getExpr(), IsKnownNonNull);
1848 case Expr::CXXTypeidExprClass:
1851 case Expr::ObjCMessageExprClass:
1853 case Expr::ObjCIvarRefExprClass:
1855 case Expr::StmtExprClass:
1857 case Expr::UnaryOperatorClass:
1859 case Expr::ArraySubscriptExprClass:
1861 case Expr::MatrixSingleSubscriptExprClass:
1863 case Expr::MatrixSubscriptExprClass:
1865 case Expr::ArraySectionExprClass:
1867 case Expr::ExtVectorElementExprClass:
1869 case Expr::MatrixElementExprClass:
1871 case Expr::CXXThisExprClass:
1873 case Expr::MemberExprClass:
1875 case Expr::CompoundLiteralExprClass:
1877 case Expr::ConditionalOperatorClass:
1879 case Expr::BinaryConditionalOperatorClass:
1881 case Expr::ChooseExprClass:
1883 case Expr::OpaqueValueExprClass:
1885 case Expr::SubstNonTypeTemplateParmExprClass:
1888 case Expr::ImplicitCastExprClass:
1889 case Expr::CStyleCastExprClass:
1890 case Expr::CXXFunctionalCastExprClass:
1891 case Expr::CXXStaticCastExprClass:
1892 case Expr::CXXDynamicCastExprClass:
1893 case Expr::CXXReinterpretCastExprClass:
1894 case Expr::CXXConstCastExprClass:
1895 case Expr::CXXAddrspaceCastExprClass:
1896 case Expr::ObjCBridgedCastExprClass:
1899 case Expr::MaterializeTemporaryExprClass:
1902 case Expr::CoawaitExprClass:
1904 case Expr::CoyieldExprClass:
1906 case Expr::PackIndexingExprClass:
1908 case Expr::HLSLOutArgExprClass:
1909 llvm_unreachable(
"cannot emit a HLSL out argument directly");
1916 assert(
type.isCanonical());
1917 assert(!
type->isReferenceType());
1925 if (
const auto *RT = dyn_cast<RecordType>(
type))
1926 if (
const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
1928 if (RD->hasMutableFields() || !RD->isTrivial())
1950 if (
const auto *ref = dyn_cast<ReferenceType>(
type)) {
1974 }
else if (
const auto *var = dyn_cast<VarDecl>(
Value)) {
1984 bool resultIsReference;
1990 resultIsReference =
false;
1996 resultIsReference =
true;
2017 auto *MD = dyn_cast_or_null<CXXMethodDecl>(
CurCodeDecl);
2018 if (
isLambdaMethod(MD) && MD->getOverloadedOperator() == OO_Call) {
2021 if (
const VarDecl *VD = dyn_cast<const VarDecl>(D)) {
2022 if (!VD->hasAttr<CUDADeviceAttr>()) {
2045 if (resultIsReference)
2072 assert(
Constant &&
"not a constant");
2095 llvm::APInt &End,
bool StrictEnums,
bool StrictBool,
2098 bool IsRegularCPlusPlusEnum =
2099 CGF.
getLangOpts().CPlusPlus && StrictEnums && ED && !ED->isFixed();
2100 if (!IsBool && !IsRegularCPlusPlusEnum)
2109 ED->getValueRange(End,
Min);
2114llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
2115 llvm::APInt
Min, End;
2117 bool StrictBoolEnabled =
CGM.getCodeGenOpts().getLoadBoolFromMem() ==
2120 CGM.getCodeGenOpts().StrictEnums,
2121 StrictBoolEnabled, IsBool))
2125 return MDHelper.createRange(
Min, End);
2133 }
else if (
CGM.getCodeGenOpts().isOptimizedBuild()) {
2134 if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) {
2135 Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
2136 Load->setMetadata(llvm::LLVMContext::MD_noundef,
2137 llvm::MDNode::get(
CGM.getLLVMContext(), {}));
2144 bool HasBoolCheck =
SanOpts.has(SanitizerKind::Bool);
2145 bool HasEnumCheck =
SanOpts.has(SanitizerKind::Enum);
2146 if (!HasBoolCheck && !HasEnumCheck)
2151 bool NeedsBoolCheck = HasBoolCheck && IsBool;
2153 if (!NeedsBoolCheck && !NeedsEnumCheck)
2163 if (NeedsEnumCheck &&
2164 getContext().isTypeIgnoredBySanitizer(SanitizerKind::Enum, Ty))
2167 llvm::APInt
Min, End;
2173 NeedsEnumCheck ? SanitizerKind::SO_Enum : SanitizerKind::SO_Bool;
2176 auto CheckHandler = SanitizerHandler::LoadInvalidValue;
2181 Check =
Builder.CreateICmpULE(
Value, llvm::ConstantInt::get(Ctx, End));
2183 llvm::Value *Upper =
2184 Builder.CreateICmpSLE(
Value, llvm::ConstantInt::get(Ctx, End));
2185 llvm::Value *Lower =
2187 Check =
Builder.CreateAnd(Upper, Lower);
2191 EmitCheck(std::make_pair(Check, Kind), CheckHandler, StaticArgs,
Value);
2200 bool isNontemporal) {
2201 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
Addr.getBasePointer()))
2202 if (GV->isThreadLocal())
2208 if (ClangVecTy->isPackedVectorBoolType(
getContext())) {
2210 unsigned ValNumElems =
2213 auto *RawIntV =
Builder.CreateLoad(
Addr, Volatile,
"load_bits");
2214 const auto *RawIntTy = RawIntV->getType();
2215 assert(RawIntTy->isIntegerTy() &&
"compressed iN storage for bitvectors");
2217 auto *PaddedVecTy = llvm::FixedVectorType::get(
2218 Builder.getInt1Ty(), RawIntTy->getPrimitiveSizeInBits());
2219 llvm::Value *
V =
Builder.CreateBitCast(RawIntV, PaddedVecTy);
2232 if (VTy != NewVecTy) {
2234 llvm::Value *
V =
Builder.CreateLoad(Cast, Volatile,
"loadVecN");
2235 unsigned OldNumElements = VTy->getNumElements();
2237 std::iota(Mask.begin(), Mask.end(), 0);
2238 V =
Builder.CreateShuffleVector(
V, Mask,
"extractVec");
2253 llvm::LoadInst *Load =
Builder.CreateLoad(
Addr, Volatile);
2254 if (isNontemporal) {
2255 llvm::MDNode *Node = llvm::MDNode::get(
2256 Load->getContext(), llvm::ConstantAsMetadata::get(
Builder.getInt32(1)));
2257 Load->setMetadata(llvm::LLVMContext::MD_nontemporal, Node);
2260 CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
2272 Ty = AtomicTy->getValueType();
2280 if (StoreTy->isVectorTy() && StoreTy->getScalarSizeInBits() >
2285 unsigned MemNumElems = StoreTy->getPrimitiveSizeInBits();
2306 Ty = AtomicTy->getValueType();
2312 auto *PaddedVecTy = llvm::FixedVectorType::get(
2313 Builder.getInt1Ty(), RawIntTy->getPrimitiveSizeInBits());
2324 if (HasBoolRep &&
CGM.getCodeGenOpts().isConvertingBoolWithCmp0()) {
2338 bool IsVector =
true) {
2339 auto *ArrayTy = dyn_cast<llvm::ArrayType>(
Addr.getElementType());
2340 if (ArrayTy && IsVector) {
2341 auto ArrayElements = ArrayTy->getNumElements();
2342 auto *ArrayElementTy = ArrayTy->getElementType();
2345 ArrayElementTy = VectorTy->getElementType();
2346 ArrayElements *= VectorTy->getNumElements();
2348 auto *VectorTy = llvm::FixedVectorType::get(ArrayElementTy, ArrayElements);
2350 return Addr.withElementType(VectorTy);
2352 auto *VectorTy = dyn_cast<llvm::VectorType>(
Addr.getElementType());
2353 if (VectorTy && !IsVector) {
2354 auto *ArrayTy = llvm::ArrayType::get(
2355 VectorTy->getElementType(),
2358 return Addr.withElementType(ArrayTy);
2372 llvm::MatrixBuilder MB(CGF.
Builder);
2373 value = MB.CreateColumnMajorToRowMajorTransform(
2374 value, MatrixTy->getNumRows(), MatrixTy->getNumColumns());
2377 value->getType()->isVectorTy());
2379 lvalue.getBaseInfo(), lvalue.getTBAAInfo(), isInit,
2380 lvalue.isNontemporal());
2389 "Result must be a Constant Matrix");
2411 for (uint32_t &Idx : Indices) {
2413 unsigned Row = Idx / NumCols;
2414 unsigned Col = Idx % NumCols;
2416 Idx = MT->getColumnMajorFlattenedIndex(Row, Col);
2420 if (
Base.isSimple()) {
2424 MatAddr =
CGM.getHLSLRuntime().createBufferMatrixTempAddress(
Base, *
this);
2426 llvm::Constant *CV =
2429 CV, ResultType,
Base.getBaseInfo(),
2432 assert(
Base.isExtVectorElt() &&
"Can only subscript lvalue vec elts here!");
2434 llvm::Constant *BaseElts =
Base.getExtVectorElts();
2437 for (
unsigned Index : Indices)
2438 CElts.push_back(BaseElts->getAggregateElement(Index));
2439 llvm::Constant *CV = llvm::ConstantVector::get(CElts);
2450 bool isInit,
bool isNontemporal) {
2451 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
Addr.getBasePointer()))
2452 if (GV->isThreadLocal())
2460 if (
auto *VecTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2462 CGM.getABIInfo().getOptimalVectorMemoryType(VecTy,
getLangOpts());
2463 if (!ClangVecTy->isPackedVectorBoolType(
getContext()) &&
2464 VecTy != NewVecTy) {
2466 VecTy->getNumElements());
2467 std::iota(Mask.begin(), Mask.begin() + VecTy->getNumElements(), 0);
2471 Mask,
"extractVec");
2474 if (
Addr.getElementType() != SrcTy)
2475 Addr =
Addr.withElementType(SrcTy);
2492 if (isNontemporal) {
2493 llvm::MDNode *Node =
2494 llvm::MDNode::get(Store->getContext(),
2495 llvm::ConstantAsMetadata::get(
Builder.getInt32(1)));
2496 Store->setMetadata(llvm::LLVMContext::MD_nontemporal, Node);
2499 CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
2518 assert(LV.getType()->isConstantMatrixType());
2528 LV.setAddress(
Addr);
2533 llvm::MatrixBuilder MB(CGF.
Builder);
2534 Value = MB.CreateRowMajorToColumnMajorTransform(
2535 Value, MatrixTy->getNumRows(), MatrixTy->getNumColumns());
2552 llvm_unreachable(
"bad evaluation kind");
2618 EltTy = MatTy->getElementType();
2619 if (
CGM.getCodeGenOpts().isOptimizedBuild()) {
2620 llvm::MatrixBuilder MB(
Builder);
2621 MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened());
2624 llvm::LoadInst *Load =
2626 llvm::Value *Elt =
Builder.CreateExtractElement(Load, Idx,
"matrixext");
2635 unsigned NumLanes = NumCols;
2639 llvm::Constant *ColConstsIndices =
nullptr;
2640 llvm::MatrixBuilder MB(
Builder);
2644 NumLanes = llvm::cast<llvm::FixedVectorType>(ColConstsIndices->getType())
2648 llvm::Type *RowTy = llvm::FixedVectorType::get(ElemTy, NumLanes);
2649 llvm::Value *
Result = llvm::PoisonValue::get(RowTy);
2651 for (
unsigned Col = 0; Col < NumLanes; ++Col) {
2652 llvm::Value *ColIdx;
2653 if (ColConstsIndices)
2654 ColIdx = ColConstsIndices->getAggregateElement(Col);
2656 ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
2658 llvm::Value *EltIndex =
2659 MB.CreateIndex(Row, ColIdx, NumRows, NumCols, IsMatrixRowMajor);
2660 llvm::Value *Elt =
Builder.CreateExtractElement(MatrixVec, EltIndex);
2661 llvm::Value *Lane = llvm::ConstantInt::get(
Builder.getInt32Ty(), Col);
2668 assert(LV.
isBitField() &&
"Unknown LValue type!");
2687 const unsigned StorageSize =
2690 assert(
static_cast<unsigned>(Offset + Info.
Size) <= StorageSize);
2691 unsigned HighBits = StorageSize - Offset - Info.
Size;
2693 Val =
Builder.CreateShl(Val, HighBits,
"bf.shl");
2694 if (Offset + HighBits)
2695 Val =
Builder.CreateAShr(Val, Offset + HighBits,
"bf.ashr");
2698 Val =
Builder.CreateLShr(Val, Offset,
"bf.lshr");
2699 if (
static_cast<unsigned>(Offset) + Info.
Size < StorageSize)
2701 Val, llvm::APInt::getLowBitsSet(StorageSize, Info.
Size),
"bf.clear");
2717 llvm::Type *DstTy = llvm::FixedVectorType::get(Vec->getType(), 1);
2718 llvm::Value *
Zero = llvm::Constant::getNullValue(
CGM.Int64Ty);
2719 Vec =
Builder.CreateInsertElement(DstTy, Vec,
Zero,
"cast.splat");
2729 llvm::Value *Elt = llvm::ConstantInt::get(
SizeTy, InIdx);
2731 llvm::Value *Element =
Builder.CreateExtractElement(Vec, Elt);
2734 if (Element->getType()->getPrimitiveSizeInBits() >
2735 LVTy->getPrimitiveSizeInBits()) {
2737 CGM.getCodeGenOpts().isConvertingBoolWithCmp0())
2738 Element =
Builder.CreateICmpNE(
2739 Element, llvm::Constant::getNullValue(Element->getType()));
2741 Element =
Builder.CreateTrunc(Element, LVTy);
2751 for (
unsigned i = 0; i != NumResultElts; ++i)
2754 Vec =
Builder.CreateShuffleVector(Vec, Mask);
2757 if (
CGM.getCodeGenOpts().isConvertingBoolWithCmp0())
2758 Vec =
Builder.CreateICmpNE(Vec,
2759 llvm::Constant::getNullValue(Vec->getType()));
2771 llvm::Type *VectorElementTy =
CGM.getTypes().ConvertType(EQT);
2779 Builder.CreateConstInBoundsGEP(CastToPointerElement, ix,
2782 return VectorBasePtrPlusIx;
2788 "Bad type for register variable");
2793 llvm::Type *OrigTy =
CGM.getTypes().ConvertType(LV.
getType());
2794 llvm::Type *Ty = OrigTy;
2795 if (OrigTy->isPointerTy())
2796 Ty =
CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
2797 llvm::Type *Types[] = { Ty };
2799 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
2801 F, llvm::MetadataAsValue::get(Ty->getContext(), RegName));
2802 if (OrigTy->isPointerTy())
2820 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2822 CGM.getDataLayout().getPrefTypeAlign(ElemTy));
2824 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2825 "vector element type must be at least byte-sized");
2828 if (Val->getType()->getPrimitiveSizeInBits() <
2829 ElemTy->getScalarSizeInBits())
2830 Val =
Builder.CreateZExt(Val, ElemTy->getScalarType());
2833 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2835 Builder.CreateGEP(DstAddr, {
Zero, Idx}, DestAddrTy, ElemAlign);
2843 llvm::Type *VecTy = Vec->getType();
2846 if (VecTy->isVectorTy() && SrcVal->getType()->getPrimitiveSizeInBits() <
2847 VecTy->getScalarSizeInBits())
2848 SrcVal =
Builder.CreateZExt(SrcVal, VecTy->getScalarType());
2850 auto *IRStoreTy = dyn_cast<llvm::IntegerType>(Vec->getType());
2852 auto *IRVecTy = llvm::FixedVectorType::get(
2853 Builder.getInt1Ty(), IRStoreTy->getPrimitiveSizeInBits());
2854 Vec =
Builder.CreateBitCast(Vec, IRVecTy);
2861 if (
auto *EltTy = dyn_cast<llvm::FixedVectorType>(SrcVal->getType());
2862 EltTy && EltTy->getNumElements() == 1)
2863 SrcVal =
Builder.CreateBitCast(SrcVal, EltTy->getElementType());
2869 Vec =
Builder.CreateBitCast(Vec, IRStoreTy);
2893 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2895 CGM.getDataLayout().getPrefTypeAlign(ElemTy));
2897 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2898 "matrix element type must be at least byte-sized");
2901 if (Val->getType()->getPrimitiveSizeInBits() <
2902 ElemTy->getScalarSizeInBits())
2903 Val =
Builder.CreateZExt(Val, ElemTy->getScalarType());
2906 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2908 Builder.CreateGEP(DstAddr, {
Zero, Idx}, DestAddrTy, ElemAlign);
2914 if (
CGM.getCodeGenOpts().isOptimizedBuild()) {
2916 llvm::MatrixBuilder MB(
Builder);
2917 MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened());
2922 Builder.CreateInsertElement(Load, InsertVal, Idx,
"matins");
2933 "Store through matrix row LValues is only implemented for HLSL!");
2939 unsigned NumLanes = NumCols;
2943 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2947 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2948 "matrix element type must be at least byte-sized");
2951 if (RowVal->getType()->getScalarType()->getPrimitiveSizeInBits() <
2952 ElemTy->getScalarSizeInBits()) {
2954 llvm::Type *StorageElmTy = llvm::FixedVectorType::get(
2955 ElemTy->getScalarType(), RowValVecTy->getNumElements());
2956 RowVal =
Builder.CreateZExt(RowVal, StorageElmTy);
2959 llvm::MatrixBuilder MB(
Builder);
2961 llvm::Constant *ColConstsIndices =
nullptr;
2965 llvm::cast<llvm::FixedVectorType>(ColConstsIndices->getType())
2970 for (
unsigned Col = 0; Col < NumLanes; ++Col) {
2971 llvm::Value *ColIdx;
2972 if (ColConstsIndices)
2973 ColIdx = ColConstsIndices->getAggregateElement(Col);
2975 ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
2977 llvm::Value *EltIndex =
2978 MB.CreateIndex(Row, ColIdx, NumRows, NumCols, IsMatrixRowMajor);
2979 llvm::Value *Lane = llvm::ConstantInt::get(
Builder.getInt32Ty(), Col);
2980 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2981 llvm::Value *NewElt =
Builder.CreateExtractElement(RowVal, Lane);
2983 Builder.CreateGEP(DstAddr, {
Zero, EltIndex}, DestAddrTy, ElemAlign);
2990 assert(Dst.
isBitField() &&
"Unknown LValue type");
3005 llvm_unreachable(
"present but none");
3040 CGM.getObjCRuntime().EmitObjCWeakAssign(*
this, src, LvalueDst);
3053 RHS =
Builder.CreatePtrToInt(RHS, ResultType,
"sub.ptr.rhs.cast");
3055 ResultType,
"sub.ptr.lhs.cast");
3056 llvm::Value *BytesBetween =
Builder.CreateSub(LHS, RHS,
"ivar.offset");
3057 CGM.getObjCRuntime().EmitObjCIvarAssign(*
this, src, dst, BytesBetween);
3059 CGM.getObjCRuntime().EmitObjCGlobalAssign(*
this, src, LvalueDst,
3063 CGM.getObjCRuntime().EmitObjCStrongCastAssign(*
this, src, LvalueDst);
3067 assert(Src.
isScalar() &&
"Can't emit an agg store with this method");
3081 SrcVal =
Builder.CreateIntCast(SrcVal, Ptr.getElementType(),
3083 llvm::Value *MaskedVal = SrcVal;
3085 const bool UseVolatile =
3088 const unsigned StorageSize =
3093 if (StorageSize != Info.
Size) {
3094 assert(StorageSize > Info.
Size &&
"Invalid bitfield size.");
3101 SrcVal, llvm::APInt::getLowBitsSet(StorageSize, Info.
Size),
3105 SrcVal =
Builder.CreateShl(SrcVal, Offset,
"bf.shl");
3109 Val, ~llvm::APInt::getBitsSet(StorageSize, Offset, Offset + Info.
Size),
3113 SrcVal =
Builder.CreateOr(Val, SrcVal,
"bf.set");
3115 assert(Offset == 0);
3122 CGM.getCodeGenOpts().ForceAAPCSBitfieldLoad)
3123 Builder.CreateLoad(Ptr,
true,
"bf.load");
3132 llvm::Value *ResultVal = MaskedVal;
3136 assert(Info.
Size <= StorageSize);
3137 unsigned HighBits = StorageSize - Info.
Size;
3139 ResultVal =
Builder.CreateShl(ResultVal, HighBits,
"bf.result.shl");
3140 ResultVal =
Builder.CreateAShr(ResultVal, HighBits,
"bf.result.ashr");
3156 SrcVal->getType()->getScalarSizeInBits())
3165 if (!DestAddrTy->isVectorTy()) {
3167 "this should only occur for non-vector l-values");
3180 CGM.getDataLayout().getPrefTypeAlign(DestAddrTy->getScalarType()));
3181 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
3183 for (
unsigned I = 0; I != NumSrcElts; ++I) {
3184 llvm::Value *Val = VTy ?
Builder.CreateExtractElement(
3185 SrcVal, llvm::ConstantInt::get(
Int32Ty, I))
3192 DstElemAddr =
Builder.CreateGEP(
3193 DstAddr, {
Zero, llvm::ConstantInt::get(
Int32Ty, FieldNo)},
3194 DestAddrTy, ElemAlign);
3203 llvm::Type *VecTy = Vec->getType();
3206 unsigned NumSrcElts = VTy->getNumElements();
3208 if (NumDstElts == NumSrcElts) {
3213 for (
unsigned i = 0; i != NumSrcElts; ++i)
3216 Vec =
Builder.CreateShuffleVector(SrcVal, Mask);
3217 }
else if (NumDstElts > NumSrcElts) {
3223 for (
unsigned i = 0; i != NumSrcElts; ++i)
3224 ExtMask.push_back(i);
3225 ExtMask.resize(NumDstElts, -1);
3226 llvm::Value *ExtSrcVal =
Builder.CreateShuffleVector(SrcVal, ExtMask);
3229 for (
unsigned i = 0; i != NumDstElts; ++i)
3239 for (
unsigned i = 0; i != NumSrcElts; ++i)
3241 Vec =
Builder.CreateShuffleVector(Vec, ExtSrcVal, Mask);
3244 llvm_unreachable(
"unexpected shorten vector length");
3250 llvm::Value *Elt = llvm::ConstantInt::get(
SizeTy, InIdx);
3252 Vec =
Builder.CreateInsertElement(Vec, SrcVal, Elt);
3262 "Bad type for register variable");
3265 assert(RegName &&
"Register LValue is not metadata");
3268 llvm::Type *OrigTy =
CGM.getTypes().ConvertType(Dst.
getType());
3269 llvm::Type *Ty = OrigTy;
3270 if (OrigTy->isPointerTy())
3271 Ty =
CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
3272 llvm::Type *Types[] = { Ty };
3274 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
3276 if (OrigTy->isPointerTy())
3279 F, {llvm::MetadataAsValue::get(Ty->getContext(), RegName),
Value});
3287 bool IsMemberAccess=
false) {
3299 LV.setObjCIvar(
false);
3303 LV.setObjCIvar(
true);
3305 LV.setBaseIvarExp(Exp->getBase());
3310 if (
const auto *Exp = dyn_cast<DeclRefExpr>(E)) {
3311 if (
const auto *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
3312 if (VD->hasGlobalStorage()) {
3313 LV.setGlobalObjCRef(
true);
3321 if (
const auto *Exp = dyn_cast<UnaryOperator>(E)) {
3326 if (
const auto *Exp = dyn_cast<ParenExpr>(E)) {
3328 if (LV.isObjCIvar()) {
3335 LV.setObjCIvar(
false);
3340 if (
const auto *Exp = dyn_cast<GenericSelectionExpr>(E)) {
3345 if (
const auto *Exp = dyn_cast<ImplicitCastExpr>(E)) {
3350 if (
const auto *Exp = dyn_cast<CStyleCastExpr>(E)) {
3355 if (
const auto *Exp = dyn_cast<ObjCBridgedCastExpr>(E)) {
3360 if (
const auto *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
3362 if (LV.isObjCIvar() && !LV.isObjCArray())
3365 LV.setObjCIvar(
false);
3366 else if (LV.isGlobalObjCRef() && !LV.isObjCArray())
3369 LV.setGlobalObjCRef(
false);
3373 if (
const auto *Exp = dyn_cast<MemberExpr>(E)) {
3387 CGF, VD,
Addr, Loc);
3392 Addr =
Addr.withElementType(RealVarTy);
3398 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3399 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3404 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Local ||
3405 ((*Res == OMPDeclareTargetDeclAttr::MT_To ||
3406 *Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
3409 assert(((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||
3410 ((*Res == OMPDeclareTargetDeclAttr::MT_To ||
3411 *Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
3413 "Expected link clause OR to clause with unified memory enabled.");
3423 llvm::LoadInst *Load =
3428 PTy, PointeeBaseInfo, PointeeTBAAInfo,
true);
3431 llvm::MDBuilder MDB(Ctx);
3433 if (
CGM.getTypes().getTargetAddressSpace(PTy) == 0 &&
3434 !
CGM.getCodeGenOpts().NullPointerIsValid)
3435 Load->setMetadata(llvm::LLVMContext::MD_nonnull,
3436 llvm::MDNode::get(Ctx, {}));
3442 llvm::LLVMContext::MD_align,
3443 llvm::MDNode::get(Ctx, MDB.createConstant(llvm::ConstantInt::get(
3444 Builder.getInt64Ty(), AlignVal))));
3449 true, PointeeBaseInfo,
3459 PointeeBaseInfo, PointeeTBAAInfo);
3469 BaseInfo, TBAAInfo);
3499 std::optional<LValue> LV =
3508 V = CGF.
Builder.CreateThreadLocalAddress(
V);
3516 VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
3531 if (FD->
hasAttr<WeakRefAttr>()) {
3546 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
V))
3547 V = llvm::NoCFIValue::get(GV);
3554 llvm::Value *ThisValue) {
3567 AsmLabelAttr *
Asm = VD->
getAttr<AsmLabelAttr>();
3568 assert(
Asm->getLabel().size() < 64-Name.size() &&
3569 "Register name too big");
3570 Name.append(
Asm->getLabel());
3571 llvm::NamedMDNode *M =
3572 CGM.
getModule().getOrInsertNamedMetadata(Name);
3573 if (M->getNumOperands() == 0) {
3576 llvm::Metadata *Ops[] = {Str};
3583 llvm::MetadataAsValue::get(CGM.
getLLVMContext(), M->getOperand(0));
3626 case llvm::GlobalValue::ExternalLinkage:
3627 case llvm::GlobalValue::LinkOnceODRLinkage:
3628 case llvm::GlobalValue::WeakODRLinkage:
3629 case llvm::GlobalValue::InternalLinkage:
3630 case llvm::GlobalValue::PrivateLinkage:
3643 "Expected OpenMP captured region");
3644 assert(
CGM.getLangOpts().OpenMP &&
"Expected OpenMP to be enabled");
3647 It != LocalDeclMap.end())
3655 QualType DREType = DD->getType().getNonReferenceType();
3666 llvm::Type *ExpectedTy =
CGM.getTypes().ConvertTypeForMem(DDType);
3674 auto It = LocalDeclMap.find(DD);
3675 bool WasMapped = It != LocalDeclMap.end();
3678 if (DD->getType()->isReferenceType()) {
3684 It->second = MapAddr;
3686 LocalDeclMap.insert({DD, MapAddr});
3687 llvm::scope_exit Guard([&] {
3689 auto RestoreIt = LocalDeclMap.find(DD);
3690 assert(RestoreIt != LocalDeclMap.end() &&
"DD should still be in map");
3691 RestoreIt->second = SavedAddr;
3693 LocalDeclMap.erase(DD);
3705 "should not emit an unevaluated operand");
3707 if (
const auto *VD = dyn_cast<VarDecl>(ND)) {
3710 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
3718 (VD->getType()->isReferenceType() ||
3720 VD->getAnyInitializer(VD);
3722 E->
getLocation(), *VD->evaluateValue(), VD->getType());
3723 assert(Val &&
"failed to emit constant expression");
3726 if (!VD->getType()->isReferenceType()) {
3728 Addr =
CGM.createUnnamedGlobalFrom(*VD, Val,
3731 auto *PTy = llvm::PointerType::get(
3750 VD = VD->getCanonicalDecl();
3754 auto I = LocalDeclMap.find(VD);
3755 if (I != LocalDeclMap.end()) {
3757 if (VD->getType()->isReferenceType())
3765 CGM.getOpenMPRuntime().isNontemporalDecl(VD))
3782 CGM.getOpenMPRuntime().isNontemporalDecl(VD))
3798 "Should not use decl without marking it used!");
3800 if (ND->
hasAttr<WeakRefAttr>()) {
3806 if (
const auto *VD = dyn_cast<VarDecl>(ND)) {
3808 if (VD->hasLinkage() || VD->isStaticDataMember())
3814 auto iter = LocalDeclMap.find(VD);
3815 if (iter != LocalDeclMap.end()) {
3816 addr = iter->second;
3820 }
else if (VD->isStaticLocal()) {
3821 llvm::Constant *var =
CGM.getOrCreateStaticVarDecl(
3822 *VD,
CGM.getLLVMLinkageVarDefinition(VD));
3828 llvm_unreachable(
"DeclRefExpr for Decl not entered in LocalDeclMap?");
3839 VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
3846 bool isBlockByref = VD->isEscapingByref();
3852 LValue LV = VD->getType()->isReferenceType() ?
3856 bool isLocalStorage = VD->hasLocalStorage();
3858 bool NonGCable = isLocalStorage &&
3859 !VD->getType()->isReferenceType() &&
3866 bool isImpreciseLifetime =
3867 (isLocalStorage && !VD->hasAttr<ObjCPreciseLifetimeAttr>());
3868 if (isImpreciseLifetime)
3874 if (
const auto *FD = dyn_cast<FunctionDecl>(ND))
3880 if (
const auto *BD = dyn_cast<BindingDecl>(ND)) {
3882 auto ApplyNontemporal = [&](
LValue LV) {
3884 CGM.getOpenMPRuntime().isNontemporalDecl(BD))
3885 LV.setNontemporal(
true);
3890 auto It = LocalDeclMap.find(BD->getCanonicalDecl());
3891 if (It != LocalDeclMap.end()) {
3892 return ApplyNontemporal(
3899 CGM.getLangOpts().OpenMP) {
3900 auto NameIt = OMPPrivatizedBindings.find(
3902 if (NameIt != OMPPrivatizedBindings.end()) {
3924 if (
const auto *GD = dyn_cast<MSGuidDecl>(ND))
3928 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
3932 if (AS !=
T.getAddressSpace()) {
3935 llvm::PointerType::get(
CGM.getLLVMContext(), TargetAS);
3936 llvm::Constant *ASC =
CGM.performAddrSpaceCast(ATPO.
getPointer(), PtrTy);
3943 llvm_unreachable(
"Unhandled DeclRefExpr");
3953 default: llvm_unreachable(
"Unknown unary operator lvalue!");
3956 assert(!
T.isNull() &&
"CodeGenFunction::EmitUnaryOpLValue: Illegal type");
3978 assert(LV.
isSimple() &&
"real/imag on non-ordinary l-value");
3995 CGM.getTBAAInfoForSubobject(LV,
T));
4002 bool isInc = E->
getOpcode() == UO_PreInc;
4025 assert(SL !=
nullptr &&
"No StringLiteral name in PredefinedExpr");
4026 StringRef FnName =
CurFn->getName();
4027 FnName.consume_front(
"\01");
4028 StringRef NameItems[] = {
4030 std::string GVName = llvm::join(NameItems, NameItems + 2,
".");
4031 if (
auto *BD = dyn_cast_or_null<BlockDecl>(
CurCodeDecl)) {
4032 std::string Name = std::string(SL->getString());
4033 if (!Name.empty()) {
4034 unsigned Discriminator =
4035 CGM.getCXXABI().getMangleContext().getBlockId(BD,
true);
4037 Name +=
"_" + Twine(Discriminator + 1).str();
4038 auto C =
CGM.GetAddrOfConstantCString(Name, GVName);
4041 auto C =
CGM.GetAddrOfConstantCString(std::string(FnName), GVName);
4045 auto C =
CGM.GetAddrOfConstantStringFromLiteral(SL, GVName);
4062 if (llvm::Constant *
C =
CGM.getTypeDescriptorFromMap(
T))
4067 bool IsBitInt =
false;
4069 if (
T->isIntegerType()) {
4072 (
T->isSignedIntegerType() ? 1 : 0);
4076 if (
T->isSignedIntegerType() &&
T->getAs<
BitIntType>()) {
4079 " non positive amount of bits in __BitInt type");
4081 " too many bits in __BitInt type");
4088 }
else if (
T->isFloatingType()) {
4097 (
intptr_t)
T.getAsOpaquePtr(), StringRef(),
4098 StringRef(), {}, Buffer, {});
4103 char S[6] = {
'\0',
'\0',
'\0',
'\0',
'\0',
'\0'};
4106 llvm::support::endian::write32(S + 1, Bits,
4108 ? llvm::endianness::big
4109 : llvm::endianness::little);
4110 StringRef Str = StringRef(S,
sizeof(S) /
sizeof(
decltype(S[0])));
4114 llvm::Constant *Components[] = {
4118 llvm::Constant *Descriptor = llvm::ConstantStruct::getAnon(Components);
4120 auto *GV =
new llvm::GlobalVariable(
4121 CGM.getModule(), Descriptor->getType(),
4122 true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
4123 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4124 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(GV);
4127 CGM.setTypeDescriptorInMap(
T, GV);
4135 if (
V->getType() == TargetTy)
4140 if (
V->getType()->isFloatingPointTy()) {
4141 unsigned Bits =
V->getType()->getPrimitiveSizeInBits().getFixedValue();
4142 if (Bits <= TargetTy->getIntegerBitWidth())
4148 if (
V->getType()->isIntegerTy() &&
4149 V->getType()->getIntegerBitWidth() <= TargetTy->getIntegerBitWidth())
4150 return Builder.CreateZExt(
V, TargetTy);
4153 if (!
V->getType()->isPointerTy()) {
4156 V = Ptr.getPointer();
4158 return Builder.CreatePtrToInt(
V, TargetTy);
4171 llvm::Constant *Filename;
4178 int PathComponentsToStrip =
4179 CGM.getCodeGenOpts().EmitCheckPathComponentsToStrip;
4180 if (PathComponentsToStrip < 0) {
4181 assert(PathComponentsToStrip !=
INT_MIN);
4182 int PathComponentsToKeep = -PathComponentsToStrip;
4183 auto I = llvm::sys::path::rbegin(FilenameString);
4184 auto E = llvm::sys::path::rend(FilenameString);
4185 while (I != E && --PathComponentsToKeep)
4188 FilenameString = FilenameString.substr(I - E);
4189 }
else if (PathComponentsToStrip > 0) {
4190 auto I = llvm::sys::path::begin(FilenameString);
4191 auto E = llvm::sys::path::end(FilenameString);
4192 while (I != E && PathComponentsToStrip--)
4197 FilenameString.substr(I - llvm::sys::path::begin(FilenameString));
4199 FilenameString = llvm::sys::path::filename(FilenameString);
4203 CGM.GetAddrOfConstantCString(std::string(FilenameString),
".src");
4204 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(
4206 FilenameGV.getPointer()->stripPointerCasts()));
4207 Filename = FilenameGV.getPointer();
4211 Filename = llvm::Constant::getNullValue(
Int8PtrTy);
4218 return llvm::ConstantStruct::getAnon(
Data);
4223enum class CheckRecoverableKind {
4234static CheckRecoverableKind
4236 if (Ordinal == SanitizerKind::SO_Vptr)
4237 return CheckRecoverableKind::AlwaysRecoverable;
4238 else if (Ordinal == SanitizerKind::SO_Return ||
4239 Ordinal == SanitizerKind::SO_Unreachable)
4240 return CheckRecoverableKind::Unrecoverable;
4242 return CheckRecoverableKind::Recoverable;
4246struct SanitizerHandlerInfo {
4247 char const *
const Name;
4253#define SANITIZER_CHECK(Enum, Name, Version, Msg) {#Name, Version},
4255#undef SANITIZER_CHECK
4259 llvm::FunctionType *FnType,
4262 CheckRecoverableKind RecoverKind,
bool IsFatal,
4263 llvm::BasicBlock *ContBB,
bool NoMerge) {
4264 assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
4265 std::optional<ApplyDebugLocation> DL;
4266 if (!CGF.
Builder.getCurrentDebugLocation()) {
4270 bool NeedsAbortSuffix =
4271 IsFatal && RecoverKind != CheckRecoverableKind::Unrecoverable;
4273 bool HandlerPreserveAllRegs =
4276 const StringRef CheckName = CheckInfo.Name;
4277 std::string FnName =
"__ubsan_handle_" + CheckName.str();
4278 if (CheckInfo.Version && !MinimalRuntime)
4279 FnName +=
"_v" + llvm::utostr(CheckInfo.Version);
4281 FnName +=
"_minimal";
4282 if (NeedsAbortSuffix)
4284 if (HandlerPreserveAllRegs && !NeedsAbortSuffix)
4285 FnName +=
"_preserve";
4287 !IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable;
4291 B.addAttribute(llvm::Attribute::NoReturn)
4292 .addAttribute(llvm::Attribute::NoUnwind);
4294 B.addUWTableAttr(llvm::UWTableKind::Default);
4299 llvm::AttributeList::FunctionIndex, B),
4305 HandlerCall->addFnAttr(llvm::Attribute::NoMerge);
4306 if (HandlerPreserveAllRegs && !NeedsAbortSuffix) {
4308 HandlerCall->setCallingConv(llvm::CallingConv::PreserveAll);
4311 HandlerCall->setDoesNotReturn();
4312 CGF.
Builder.CreateUnreachable();
4319 ArrayRef<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Checked,
4323 assert(Checked.size() > 0);
4324 assert(CheckHandler >= 0 &&
4328 llvm::Value *FatalCond =
nullptr;
4329 llvm::Value *RecoverableCond =
nullptr;
4330 llvm::Value *TrapCond =
nullptr;
4331 bool NoMerge =
false;
4338 for (
auto &[Check, Ord] : Checked) {
4339 llvm::Value *GuardedCheck = Check;
4341 (
CGM.getCodeGenOpts().SanitizeSkipHotCutoffs[Ord] > 0)) {
4343 CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check),
4344 llvm::ConstantInt::get(
CGM.Int8Ty, Ord));
4349 llvm::Value *&Cond =
CGM.getCodeGenOpts().SanitizeTrap.has(Ord) ? TrapCond
4350 :
CGM.getCodeGenOpts().SanitizeRecover.has(Ord)
4353 Cond = Cond ?
Builder.CreateAnd(Cond, GuardedCheck) : GuardedCheck;
4355 if (!
CGM.getCodeGenOpts().SanitizeMergeHandlers.has(Ord))
4361 if (!FatalCond && !RecoverableCond)
4364 llvm::Value *JointCond;
4365 if (FatalCond && RecoverableCond)
4366 JointCond =
Builder.CreateAnd(FatalCond, RecoverableCond);
4368 JointCond = FatalCond ? FatalCond : RecoverableCond;
4372 assert(
SanOpts.has(Checked[0].second));
4374 for (
int i = 1, n = Checked.size(); i < n; ++i) {
4376 "All recoverable kinds in a single check must be same!");
4377 assert(
SanOpts.has(Checked[i].second));
4383 llvm::Instruction *Branch =
Builder.CreateCondBr(JointCond, Cont, Handlers);
4386 llvm::MDNode *Node = MDHelper.createLikelyBranchWeights();
4387 Branch->setMetadata(llvm::LLVMContext::MD_prof, Node);
4391 if (
CGM.getCodeGenOpts().SanitizeMinimalRuntime) {
4402 Args.reserve(DynamicArgs.size() + 1);
4403 ArgTypes.reserve(DynamicArgs.size() + 1);
4406 if (!StaticArgs.empty()) {
4407 llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
4408 auto *InfoPtr =
new llvm::GlobalVariable(
4409 CGM.getModule(), Info->getType(),
4412 false, llvm::GlobalVariable::PrivateLinkage, Info,
"",
4413 nullptr, llvm::GlobalVariable::NotThreadLocal,
4414 CGM.getDataLayout().getDefaultGlobalsAddressSpace());
4415 InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4416 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
4417 Args.push_back(
Builder.CreateAddrSpaceCast(InfoPtr,
CGM.VoidPtrTy));
4418 ArgTypes.push_back(
CGM.VoidPtrTy);
4421 for (llvm::Value *DynamicArg : DynamicArgs) {
4426 llvm::FunctionType *FnType =
4427 llvm::FunctionType::get(
CGM.VoidTy, ArgTypes,
false);
4429 if (!FatalCond || !RecoverableCond) {
4433 (FatalCond !=
nullptr), Cont, NoMerge);
4437 llvm::BasicBlock *NonFatalHandlerBB =
4440 Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
4443 NonFatalHandlerBB, NoMerge);
4454 llvm::ConstantInt *TypeId, llvm::Value *Ptr,
4459 llvm::CondBrInst *BI =
Builder.CreateCondBr(Cond, Cont, CheckBB);
4462 llvm::MDNode *Node = MDHelper.createLikelyBranchWeights();
4463 BI->setMetadata(llvm::LLVMContext::MD_prof, Node);
4467 bool WithDiag = !
CGM.getCodeGenOpts().SanitizeTrap.has(Ordinal);
4469 llvm::CallInst *CheckCall;
4470 llvm::FunctionCallee SlowPathFn;
4472 llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
4474 new llvm::GlobalVariable(
CGM.getModule(), Info->getType(),
false,
4475 llvm::GlobalVariable::PrivateLinkage, Info);
4476 InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4477 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
4479 SlowPathFn =
CGM.getModule().getOrInsertFunction(
4480 "__cfi_slowpath_diag",
4483 CheckCall =
Builder.CreateCall(SlowPathFn, {TypeId, Ptr, InfoPtr});
4485 SlowPathFn =
CGM.getModule().getOrInsertFunction(
4488 CheckCall =
Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
4493 CheckCall->setDoesNotThrow();
4501 llvm::Module *M = &
CGM.getModule();
4503 QualType QInt64Ty =
C.getIntTypeForBitwidth(64,
false);
4505 auto *ArgCallsiteTypeId =
4509 auto *ArgCFICheckFailData =
4513 CGM.getTypes().arrangeBuiltinFunctionDeclaration(
C.VoidTy,
FnArgs);
4515 llvm::Function *F = llvm::Function::Create(
4517 llvm::GlobalValue::WeakAnyLinkage,
"__cfi_check", M);
4519 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
4520 F->setAlignment(llvm::Align(4096));
4523 llvm::LLVMContext &Ctx = M->getContext();
4524 llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx,
"entry", F);
4527 llvm::CallInst::Create(M->getFunction(
"__cfi_check_fail"), Args,
"", BB);
4528 llvm::ReturnInst::Create(Ctx,
nullptr, BB);
4539 auto CheckHandler = SanitizerHandler::CFICheckFail;
4546 {SanitizerKind::SO_CFIVCall, SanitizerKind::SO_CFINVCall,
4547 SanitizerKind::SO_CFIDerivedCast, SanitizerKind::SO_CFIUnrelatedCast,
4548 SanitizerKind::SO_CFIICall},
4559 llvm::Function *F = llvm::Function::Create(
4561 llvm::GlobalValue::WeakODRLinkage,
"__cfi_check_fail", &
CGM.getModule());
4564 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
4565 F->setVisibility(llvm::GlobalValue::HiddenVisibility);
4579 CGM.getContext().VoidPtrTy, ArgData->getLocation());
4582 CGM.getContext().VoidPtrTy, ArgAddr->getLocation());
4585 llvm::Value *DataIsNotNullPtr =
4590 EmitTrapCheck(DataIsNotNullPtr, SanitizerHandler::CFICheckFail,
4593 llvm::StructType *SourceLocationTy =
4595 llvm::StructType *CfiCheckFailDataTy =
4598 llvm::Value *
V =
Builder.CreateConstGEP2_32(
4602 llvm::Value *CheckKind =
Builder.CreateLoad(CheckKindAddr);
4604 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
4605 CGM.getLLVMContext(),
4606 llvm::MDString::get(
CGM.getLLVMContext(),
"all-vtables"));
4607 llvm::Value *ValidVtable =
Builder.CreateZExt(
4608 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::type_test),
4609 {Addr, AllVtables}),
4612 const std::pair<int, SanitizerKind::SanitizerOrdinal> CheckKinds[] = {
4619 for (
auto CheckKindOrdinalPair : CheckKinds) {
4620 int Kind = CheckKindOrdinalPair.first;
4627 Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(
Int8Ty, Kind));
4628 if (
CGM.getLangOpts().Sanitize.has(Ordinal))
4629 EmitCheck(std::make_pair(Cond, Ordinal), SanitizerHandler::CFICheckFail,
4642 CGM.addUsedGlobal(F);
4646 if (
SanOpts.has(SanitizerKind::Unreachable)) {
4647 auto CheckOrdinal = SanitizerKind::SO_Unreachable;
4648 auto CheckHandler = SanitizerHandler::BuiltinUnreachable;
4664 if ((
int)TrapBBs.size() <= CheckHandlerID)
4665 TrapBBs.resize(CheckHandlerID + 1);
4667 llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
4669 llvm::DILocation *TrapLocation =
Builder.getCurrentDebugLocation();
4670 llvm::StringRef TrapMessage;
4671 llvm::StringRef TrapCategory;
4672 auto DebugTrapReasonKind =
CGM.getCodeGenOpts().getSanitizeDebugTrapReasons();
4674 DebugTrapReasonKind ==
4680 TrapCategory =
"Undefined Behavior Sanitizer";
4684 DebugTrapReasonKind !=
4688 TrapLocation, TrapCategory, TrapMessage);
4691 NoMerge = NoMerge || !
CGM.getCodeGenOpts().isOptimizedBuild() ||
4695 if (TrapBB && !NoMerge) {
4696 auto Call = TrapBB->begin();
4699 Call->applyMergedLocation(
Call->getDebugLoc(), TrapLocation);
4701 Builder.CreateCondBr(Checked, Cont, TrapBB,
4702 MDHelper.createLikelyBranchWeights());
4705 Builder.CreateCondBr(Checked, Cont, TrapBB,
4706 MDHelper.createLikelyBranchWeights());
4711 llvm::CallInst *TrapCall;
4712 if (
CGM.getCodeGenOpts().SanitizeTrapLoop)
4714 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::looptrap));
4716 TrapCall =
Builder.CreateCall(
4717 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
4718 llvm::ConstantInt::get(
CGM.Int8Ty, CheckHandlerID));
4720 if (!
CGM.getCodeGenOpts().TrapFuncName.empty()) {
4721 auto A = llvm::Attribute::get(
getLLVMContext(),
"trap-func-name",
4722 CGM.getCodeGenOpts().TrapFuncName);
4723 TrapCall->addFnAttr(A);
4726 TrapCall->addFnAttr(llvm::Attribute::NoMerge);
4727 TrapCall->setDoesNotReturn();
4728 TrapCall->setDoesNotThrow();
4737 llvm::Function *TrapIntrinsic =
CGM.getIntrinsic(IntrID);
4738 llvm::CallInst *TrapCall =
Builder.CreateCall(TrapIntrinsic);
4740 if (!
CGM.getCodeGenOpts().TrapFuncName.empty()) {
4741 auto A = llvm::Attribute::get(
getLLVMContext(),
"trap-func-name",
4742 CGM.getCodeGenOpts().TrapFuncName);
4743 TrapCall->addFnAttr(A);
4747 TrapCall->addFnAttr(llvm::Attribute::NoMerge);
4748 if (TrapIntrinsic->doesNotThrow())
4749 TrapCall->setDoesNotThrow();
4750 if (TrapIntrinsic->doesNotReturn()) {
4751 TrapCall->setDoesNotReturn();
4756 Builder.ClearInsertionPoint();
4762 llvm::CallInst *TrapCall =
4764 TrapCall->setDoesNotReturn();
4765 TrapCall->setDoesNotThrow();
4768 Builder.ClearInsertionPoint();
4776 "Array to pointer decay must have array source type!");
4785 Addr =
Addr.withElementType(NewTy);
4791 "Expected pointer to array");
4797 Builder.CreateStructuredGEP(NewTy,
Addr.emitRawPointer(*
this), {});
4811 if (TBAAInfo) *TBAAInfo =
CGM.getTBAAAccessInfo(EltType);
4820 const auto *CE = dyn_cast<CastExpr>(E);
4821 if (!CE || CE->getCastKind() != CK_ArrayToPointerDecay)
4833 llvm::Type *elemType,
4839 const llvm::Twine &name =
"arrayidx") {
4840 if (inbounds && CGF.
getLangOpts().EmitLogicalPointer)
4841 return CGF.
Builder.CreateStructuredGEP(elemType, ptr, indices);
4855 llvm::Type *elementType,
bool inbounds,
4858 const llvm::Twine &name =
"arrayidx") {
4859 if (inbounds && CGF.
getLangOpts().EmitLogicalPointer)
4862 indices.drop_front()),
4863 elementType, align);
4875 return D && D->
hasAttr<BPFPreserveStaticOffsetAttr>();
4882 if (PointeeType.
isNull())
4895 llvm::Function *Fn =
4897 llvm::CallInst *
Call = CGF.
Builder.CreateCall(Fn, {
Addr.emitRawPointer(CGF)});
4915 if (
const auto *ME = dyn_cast<MemberExpr>(E))
4916 return ME->getMemberDecl()->hasAttr<BPFPreserveAccessIndexAttr>();
4918 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
4919 const auto *VarDef = dyn_cast<VarDecl>(DRE->getDecl());
4923 const auto *PtrT = VarDef->getType()->getAs<
PointerType>();
4929 if (
const auto *RecT = dyn_cast<RecordType>(PointeeT))
4930 return RecT->getDecl()
4931 ->getMostRecentDecl()
4932 ->
hasAttr<BPFPreserveAccessIndexAttr>();
4945 const llvm::Twine &name =
"arrayidx") {
4948 for (
auto *idx : indices.drop_back())
4967 llvm::Value *eltPtr;
4968 auto LastIndex = dyn_cast<llvm::ConstantInt>(indices.back());
4975 signedIndices, loc, eltAlign, name);
4979 unsigned idx = LastIndex->getZExtValue();
4980 llvm::DIType *DbgInfo =
nullptr;
4983 eltPtr = CGF.
Builder.CreatePreserveArrayAccessIndex(
4995struct StructFieldAccess
4996 :
public ConstStmtVisitor<StructFieldAccess, const Expr *> {
4997 const Expr *VisitCastExpr(
const CastExpr *E) {
5002 const Expr *VisitParenExpr(
const ParenExpr *E) {
5011 const FieldDecl *Field, int64_t &Offset) {
5014 unsigned FieldNo = 0;
5049 if (FD1OuterRec != FD2OuterRec)
5051 return std::optional<int64_t>();
5053 int64_t FD1Offset = 0;
5055 return std::optional<int64_t>();
5057 int64_t FD2Offset = 0;
5059 return std::optional<int64_t>();
5061 return std::make_optional<int64_t>(FD1Offset - FD2Offset);
5070 llvm::Value *BoundsVal,
5073 assert(BoundsVal->getType()->isIntegerTy());
5074 assert(!PointeeTy.
isNull() &&
"pointee type is never null");
5076 "Sema guarantees a '__sized_by' pointee is a non-function type");
5081 assert(PointeeTy->
isVoidType() &&
"expected a 'void' incomplete pointee");
5090 unsigned CountWidth = BoundsVal->getType()->getIntegerBitWidth();
5094 CountSigned ? llvm::isIntN(CountWidth, ElemSizeQ)
5095 : llvm::isUIntN(CountWidth,
static_cast<uint64_t
>(ElemSizeQ));
5100 return llvm::ConstantInt::get(BoundsVal->getType(), 0);
5102 llvm::Value *ElemSizeV =
5103 llvm::ConstantInt::get(BoundsVal->getType(), ElemSizeQ);
5108 return CountSigned ? CGF.
Builder.CreateSDiv(BoundsVal, ElemSizeV)
5109 : CGF.
Builder.CreateUDiv(BoundsVal, ElemSizeV);
5121 QualType IndexType, llvm::Value *IndexVal,
bool Accessed,
5122 bool FlexibleArray) {
5123 const auto *ME = dyn_cast<MemberExpr>(ArrayExpr->
IgnoreImpCasts());
5124 if (!ME || !ME->getMemberDecl()->getType()->isCountAttributedType())
5129 if (FlexibleArray &&
5130 !ME->isFlexibleArrayMemberLike(
getContext(), StrictFlexArraysLevel))
5138 if (std::optional<int64_t> Diff =
5157 llvm::Value *BoundsVal =
5159 Builder.getInt32(*Diff),
".counted_by.gep");
5161 ".counted_by.load");
5164 assert(CountAttributedTy &&
"expected FD to have a CountAttributedType");
5169 if (CountAttributedTy->isOrNull()) {
5172 llvm::Value *Ptr =
Builder.CreateLoad(ArrayInst);
5174 BoundsVal =
Builder.CreateSelect(
5175 IsNull, llvm::ConstantInt::get(BoundsType, 0), BoundsVal);
5182 if (CountAttributedTy->isCountInBytes())
5189 CountFD->
getType(), Accessed);
5197 llvm::Value *IdxPre =
5199 bool SignedIndices =
false;
5200 auto EmitIdxAfterBase = [&, IdxPre](
bool Promote) -> llvm::Value * {
5203 assert(E->
getRHS() == E->
getIdx() &&
"index was neither LHS nor RHS");
5209 SignedIndices |= IdxSigned;
5211 if (
SanOpts.has(SanitizerKind::ArrayBounds))
5215 if (Promote && Idx->getType() !=
IntPtrTy)
5228 auto *Idx = EmitIdxAfterBase(
false);
5229 assert(LHS.
isSimple() &&
"Can only subscript lvalue vectors here!");
5237 std::optional<LValue> LV;
5240 LV =
CGM.getHLSLRuntime().emitResourceArraySubscriptExpr(E, *
this);
5242 LV =
CGM.getHLSLRuntime().emitBufferArraySubscriptExpr(E, *
this,
5254 auto *Idx = EmitIdxAfterBase(
true);
5261 CGM.getTBAAInfoForSubobject(LV, EltType));
5273 auto *Idx = EmitIdxAfterBase(
true);
5283 Idx =
Builder.CreateMul(Idx, numElements);
5285 Idx =
Builder.CreateNSWMul(Idx, numElements);
5297 auto *Idx = EmitIdxAfterBase(
true);
5300 llvm::Value *InterfaceSizeVal =
5301 llvm::ConstantInt::get(Idx->getType(), InterfaceSize.
getQuantity());
5303 llvm::Value *ScaledIdx =
Builder.CreateMul(Idx, InterfaceSizeVal);
5309 llvm::Type *OrigBaseElemTy =
Addr.getElementType();
5314 llvm::Value *EltPtr =
5316 ScaledIdx,
false, SignedIndices, E->
getExprLoc());
5323 assert(Array->getType()->isArrayType() &&
5324 "Array to pointer decay must have array source type!");
5328 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
5332 auto *Idx = EmitIdxAfterBase(
true);
5334 if (
SanOpts.has(SanitizerKind::ArrayBounds))
5342 *
this, ArrayLV.
getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
5346 if (!
CGM.getCodeGenOpts().NewStructPathTBAA) {
5349 EltTBAAInfo =
CGM.getTBAAInfoForSubobject(ArrayLV, E->
getType());
5354 EltTBAAInfo =
CGM.getTBAAAccessInfo(E->
getType());
5376 auto *Idx = EmitIdxAfterBase(
true);
5383 if (
SanOpts.has(SanitizerKind::ArrayBounds)) {
5384 StructFieldAccess Visitor;
5387 if (
const auto *CE = dyn_cast_if_present<CastExpr>(
Base);
5388 CE && CE->getCastKind() == CK_LValueToRValue)
5421 MatAddr =
CGM.getHLSLRuntime().createBufferMatrixTempAddress(
Base, *
this);
5431 "incomplete matrix subscript expressions should be rejected during Sema");
5437 llvm::MatrixBuilder MB(
Builder);
5440 unsigned NumRows = MatrixTy->getNumRows();
5441 bool IsMatrixRowMajor =
5443 llvm::Value *FinalIdx =
5444 MB.CreateIndex(RowIdx, ColIdx, NumRows, NumCols, IsMatrixRowMajor);
5455 bool IsLowerBound) {
5457 if (
auto *ASE = dyn_cast<ArraySectionExpr>(
Base->IgnoreParenImpCasts())) {
5461 BaseInfo = BaseLVal.getBaseInfo();
5466 Addr =
Addr.withElementType(NewTy);
5472 "Expected pointer to array");
5482 BaseInfo.mergeForCast(TypeBaseInfo);
5491 bool IsLowerBound) {
5494 "OpenACC Array section codegen not implemented");
5498 if (
auto *AT =
getContext().getAsArrayType(BaseTy))
5499 ResultExprTy = AT->getElementType();
5502 llvm::Value *Idx =
nullptr;
5510 LowerBound->getType()->hasSignedIntegerRepresentation());
5512 Idx = llvm::ConstantInt::getNullValue(
IntPtrTy);
5517 auto &
C =
CGM.getContext();
5519 llvm::APSInt ConstLength;
5522 if (std::optional<llvm::APSInt>
CL = Length->getIntegerConstantExpr(
C)) {
5529 if (std::optional<llvm::APSInt> LB =
5530 LowerBound->getIntegerConstantExpr(
C)) {
5532 LowerBound =
nullptr;
5537 else if (!LowerBound)
5540 if (Length || LowerBound) {
5541 auto *LowerBoundVal =
5545 LowerBound->getType()->hasSignedIntegerRepresentation())
5546 : llvm::ConstantInt::get(
IntPtrTy, ConstLowerBound);
5551 Length->getType()->hasSignedIntegerRepresentation())
5552 : llvm::ConstantInt::get(
IntPtrTy, ConstLength);
5553 Idx =
Builder.CreateAdd(LowerBoundVal, LengthVal,
"lb_add_len",
5556 if (Length && LowerBound) {
5558 Idx, llvm::ConstantInt::get(
IntPtrTy, 1),
"idx_sub_1",
5562 Idx = llvm::ConstantInt::get(
IntPtrTy, ConstLength + ConstLowerBound);
5568 if (
auto *VAT =
C.getAsVariableArrayType(ArrayTy)) {
5569 Length = VAT->getSizeExpr();
5570 if (std::optional<llvm::APSInt> L = Length->getIntegerConstantExpr(
C)) {
5575 auto *CAT =
C.getAsConstantArrayType(ArrayTy);
5576 assert(CAT &&
"unexpected type for array initializer");
5577 ConstLength = CAT->getSize();
5580 auto *LengthVal =
Builder.CreateIntCast(
5582 Length->getType()->hasSignedIntegerRepresentation());
5584 LengthVal, llvm::ConstantInt::get(
IntPtrTy, 1),
"len_sub_1",
5589 Idx = llvm::ConstantInt::get(
IntPtrTy, ConstLength);
5598 if (
auto *VLA =
getContext().getAsVariableArrayType(ResultExprTy)) {
5604 BaseTy, VLA->getElementType(), IsLowerBound);
5613 Idx =
Builder.CreateMul(Idx, NumElements);
5615 Idx =
Builder.CreateNSWMul(Idx, NumElements);
5624 assert(Array->getType()->isArrayType() &&
5625 "Array to pointer decay must have array source type!");
5629 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
5636 *
this, ArrayLV.
getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
5637 ResultExprTy, !
getLangOpts().PointerOverflowDefined,
5640 TBAAInfo =
CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
5644 ResultExprTy, IsLowerBound);
5667 Base.getQuals().removeObjCGCAttr();
5676 "Result must be a vector");
5684 if (LTy->getScalarSizeInBits() > Vec->getType()->getScalarSizeInBits())
5685 Vec =
Builder.CreateZExt(Vec, LTy);
5686 Builder.CreateStore(Vec, VecMem);
5697 if (
Base.isSimple()) {
5698 llvm::Constant *CV =
5704 if (
Base.isMatrixRow()) {
5706 llvm::dyn_cast<llvm::ConstantInt>(
Base.getMatrixRowIdx())) {
5710 unsigned NumCols = Indices.size();
5712 unsigned Row = RowIdx->getZExtValue();
5716 QualType ElemQT = EVT->getElementType();
5719 for (
unsigned C = 0;
C < NumCols; ++
C) {
5720 unsigned Col = Indices[
C];
5721 unsigned Linear = Col * NumRows + Row;
5722 MatIndices.push_back(llvm::ConstantInt::get(
Int32Ty, Linear));
5725 llvm::Constant *ConstIdxs = llvm::ConstantVector::get(MatIndices);
5729 llvm::Constant *Cols =
5736 Base.getMatrixAddress(),
Base.getMatrixRowIdx(), Cols,
Base.getType(),
5740 assert(
Base.isExtVectorElt() &&
"Can only subscript lvalue vec elts here!");
5742 llvm::Constant *BaseElts =
Base.getExtVectorElts();
5745 for (
unsigned Index : Indices)
5746 CElts.push_back(BaseElts->getAggregateElement(Index));
5747 llvm::Constant *CV = llvm::ConstantVector::get(CElts);
5754 while (
auto *BaseMemberExpr = dyn_cast<MemberExpr>(UnderlyingBaseExpr))
5755 UnderlyingBaseExpr = BaseMemberExpr->getBase()->
IgnoreParens();
5768 return CGM.getHLSLRuntime().emitBufferMemberExpr(*
this, E);
5771 std::optional<LValue> LV;
5772 LV =
CGM.getHLSLRuntime().emitResourceMemberExpr(*
this, E);
5782 bool IsInBounds = !
getLangOpts().PointerOverflowDefined &&
5794 SkippedChecks.
set(SanitizerKind::Alignment,
true);
5796 SkippedChecks.
set(SanitizerKind::Null,
true);
5804 if (
auto *Field = dyn_cast<FieldDecl>(ND)) {
5812 CGM.getOpenMPRuntime().isNontemporalDecl(Field)) ||
5819 if (
const auto *FD = dyn_cast<FunctionDecl>(ND))
5822 llvm_unreachable(
"Unhandled member declaration!");
5829 llvm::Value *ThisValue) {
5830 bool HasExplicitObjectParameter =
false;
5831 const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
CurCodeDecl);
5833 HasExplicitObjectParameter = MD->isExplicitObjectMemberFunction();
5834 assert(MD->getParent()->isLambda());
5835 assert(MD->getParent() == Field->getParent());
5838 if (HasExplicitObjectParameter) {
5840 auto It = LocalDeclMap.find(D);
5841 assert(It != LocalDeclMap.end() &&
"explicit parameter not loaded?");
5842 Address AddrOfExplicitObject = It->getSecond();
5853 if (ThisTy != LambdaTy) {
5856 LambdaLV.
getAddress(), ThisTy, BasePathArray.begin(),
5876 unsigned FieldIndex) {
5877 unsigned I = 0, Skipped = 0;
5880 if (I == FieldIndex)
5882 if (F->isUnnamedBitField())
5887 return FieldIndex - Skipped;
5897 if (Offset.isZero())
5919 llvm::Type *StructType =
5925 {CGF.Builder.getSize(idx)}),
5940 const FieldDecl *field,
bool IsInBounds) {
5967 if (RD->isDynamicClass())
5970 for (
const auto &
Base : RD->bases())
5990 CGM.getCodeGenOpts().AAPCSBitfieldWidth &&
6021 llvm::Type *FieldIntTy = llvm::Type::getIntNTy(
getLLVMContext(), SS);
6022 Addr =
Addr.withElementType(FieldIntTy);
6057 assert(!FieldTBAAInfo.
Offset &&
6058 "Nonzero offset for an access with no base type!");
6071 FieldTBAAInfo.
Size =
6082 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
6086 addr =
Builder.CreateLaunderInvariantGroup(addr);
6129 if (field->
hasAttr<AnnotateAttr>())
6145 QualType FieldType = Field->getType();
6151 *
this,
Base.getAddress(), Field,
6156 V =
V.withElementType(llvmType);
6165 CGM.getTBAAInfoForSubobject(
Base, FieldType));
6208 assert(E->
isTransparent() &&
"non-transparent glvalue init list");
6216 const Expr *Operand) {
6217 if (
auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Operand->IgnoreParens())) {
6219 return std::nullopt;
6228std::optional<LValue> HandleConditionalOperatorLValueSimpleCase(
6230 const Expr *condExpr = E->
getCond();
6235 std::swap(Live, Dead);
6245 if (
auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Live->
IgnoreParens())) {
6256 return std::nullopt;
6258struct ConditionalInfo {
6259 llvm::BasicBlock *lhsBlock, *rhsBlock;
6260 std::optional<LValue> LHS, RHS;
6265template<
typename FuncTy>
6267 const AbstractConditionalOperator *E,
6268 const FuncTy &BranchGenFunc) {
6284 Info.lhsBlock = CGF.
Builder.GetInsertBlock();
6287 CGF.
Builder.CreateBr(endBlock);
6295 Info.rhsBlock = CGF.
Builder.GetInsertBlock();
6307 "Unexpected conditional operator!");
6312 if (HandleConditionalOperatorLValueSimpleCase(*
this, E))
6315 EmitConditionalBlocks(*
this, E, [](CodeGenFunction &CGF,
const Expr *E) {
6322 if (!
expr->isGLValue()) {
6325 "Unexpected conditional operator!");
6330 if (std::optional<LValue> Res =
6331 HandleConditionalOperatorLValueSimpleCase(*
this,
expr))
6334 ConditionalInfo Info = EmitConditionalBlocks(
6335 *
this,
expr, [](CodeGenFunction &CGF,
const Expr *E) {
6339 if ((Info.LHS && !Info.LHS->isSimple()) ||
6340 (Info.RHS && !Info.RHS->isSimple()))
6343 if (Info.LHS && Info.RHS) {
6344 Address lhsAddr = Info.LHS->getAddress();
6345 Address rhsAddr = Info.RHS->getAddress();
6347 lhsAddr, rhsAddr, Info.lhsBlock, Info.rhsBlock,
6350 std::max(Info.LHS->getBaseInfo().getAlignmentSource(),
6351 Info.RHS->getBaseInfo().getAlignmentSource());
6353 Info.LHS->getTBAAInfo(), Info.RHS->getTBAAInfo());
6357 assert((Info.LHS || Info.RHS) &&
6358 "both operands of glvalue conditional are throw-expressions?");
6359 return Info.LHS ? *Info.LHS : *Info.RHS;
6371 llvm::scope_exit RestoreCurCast([
this, Prev =
CurCast] {
CurCast = Prev; });
6376 case CK_LValueToRValueBitCast:
6377 case CK_ArrayToPointerDecay:
6378 case CK_FunctionToPointerDecay:
6379 case CK_NullToMemberPointer:
6380 case CK_NullToPointer:
6381 case CK_IntegralToPointer:
6382 case CK_PointerToIntegral:
6383 case CK_PointerToBoolean:
6384 case CK_IntegralCast:
6385 case CK_BooleanToSignedIntegral:
6386 case CK_IntegralToBoolean:
6387 case CK_IntegralToFloating:
6388 case CK_FloatingToIntegral:
6389 case CK_FloatingToBoolean:
6390 case CK_FloatingCast:
6391 case CK_FloatingRealToComplex:
6392 case CK_FloatingComplexToReal:
6393 case CK_FloatingComplexToBoolean:
6394 case CK_FloatingComplexCast:
6395 case CK_FloatingComplexToIntegralComplex:
6396 case CK_IntegralRealToComplex:
6397 case CK_IntegralComplexToReal:
6398 case CK_IntegralComplexToBoolean:
6399 case CK_IntegralComplexCast:
6400 case CK_IntegralComplexToFloatingComplex:
6401 case CK_DerivedToBaseMemberPointer:
6402 case CK_BaseToDerivedMemberPointer:
6403 case CK_MemberPointerToBoolean:
6404 case CK_ReinterpretMemberPointer:
6405 case CK_AnyPointerToBlockPointerCast:
6406 case CK_ARCProduceObject:
6407 case CK_ARCConsumeObject:
6408 case CK_ARCReclaimReturnedObject:
6409 case CK_ARCExtendBlockObject:
6410 case CK_CopyAndAutoreleaseBlockObject:
6411 case CK_IntToOCLSampler:
6412 case CK_FloatingToFixedPoint:
6413 case CK_FixedPointToFloating:
6414 case CK_FixedPointCast:
6415 case CK_FixedPointToBoolean:
6416 case CK_FixedPointToIntegral:
6417 case CK_IntegralToFixedPoint:
6419 case CK_HLSLVectorTruncation:
6420 case CK_HLSLMatrixTruncation:
6421 case CK_HLSLArrayRValue:
6422 case CK_HLSLElementwiseCast:
6423 case CK_HLSLAggregateSplatCast:
6427 llvm_unreachable(
"dependent cast kind in IR gen!");
6429 case CK_BuiltinFnToFnPtr:
6430 llvm_unreachable(
"builtin functions are handled elsewhere");
6433 case CK_NonAtomicToAtomic:
6434 case CK_AtomicToNonAtomic:
6444 case CK_ConstructorConversion:
6445 case CK_UserDefinedConversion:
6446 case CK_CPointerToObjCPointerCast:
6447 case CK_BlockPointerToObjCPointerCast:
6448 case CK_LValueToRValue:
6463 if (
V.getElementType() !=
T)
6470 case CK_UncheckedDerivedToBase:
6471 case CK_DerivedToBase: {
6485 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6489 case CK_BaseToDerived: {
6504 if (
SanOpts.has(SanitizerKind::CFIDerivedCast))
6510 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6512 case CK_LValueBitCast: {
6516 CGM.EmitExplicitCastExprType(CE,
this);
6521 if (
SanOpts.has(SanitizerKind::CFIUnrelatedCast))
6527 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6529 case CK_AddressSpaceConversion: {
6538 case CK_ObjCObjectLValueCast: {
6542 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6544 case CK_ZeroToOCLOpaqueType:
6545 llvm_unreachable(
"NULL to OpenCL opaque type lvalue cast is not valid");
6547 case CK_VectorSplat: {
6555 llvm_unreachable(
"Unhandled lvalue cast kind?");
6563std::pair<LValue, LValue>
6583 return std::make_pair(BaseLV, TempLV);
6591 llvm::Value *
Addr = TempLV.getAddress().getBasePointer();
6594 Address TmpAddr(
Addr, ElTy, TempLV.getAlignment());
6604 llvm::DenseMap<const OpaqueValueExpr*,LValue>::iterator
6605 it = OpaqueLValues.find(e);
6607 if (it != OpaqueLValues.end())
6610 assert(e->
isUnique() &&
"LValue for a nonunique OVE hasn't been emitted");
6618 llvm::DenseMap<const OpaqueValueExpr*,RValue>::iterator
6619 it = OpaqueRValues.find(e);
6621 if (it != OpaqueRValues.end())
6624 assert(e->
isUnique() &&
"RValue for a nonunique OVE hasn't been emitted");
6630 return OpaqueLValues.contains(E);
6631 return OpaqueRValues.contains(E);
6655 llvm_unreachable(
"bad evaluation kind");
6664 llvm::CallBase **CallOrInvoke) {
6665 llvm::CallBase *CallOrInvokeStorage;
6666 if (!CallOrInvoke) {
6667 CallOrInvoke = &CallOrInvokeStorage;
6670 llvm::scope_exit AddCoroElideSafeOnExit([&] {
6672 auto *I = *CallOrInvoke;
6674 I->addFnAttr(llvm::Attribute::CoroElideSafe);
6682 if (
const auto *CE = dyn_cast<CXXMemberCallExpr>(E))
6685 if (
const auto *CE = dyn_cast<CUDAKernelCallExpr>(E))
6690 if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(E))
6691 if (
const auto *MD =
6692 dyn_cast_if_present<CXXMethodDecl>(CE->getCalleeDecl());
6693 MD && MD->isImplicitObjectMemberFunction())
6708 nullptr, CallOrInvoke);
6714 llvm::CallBase **CallOrInvoke) {
6717 nullptr, CallOrInvoke);
6724 std::string NoBuiltinFD = (
"no-builtin-" + FD->
getName()).str();
6725 std::string NoBuiltins =
"no-builtins";
6728 std::string FDInlineName = (Ident +
".inline").str();
6730 bool IsPredefinedLibFunction =
6732 bool HasAttributeNoBuiltin =
6733 CGF.
CurFn->getAttributes().hasFnAttr(NoBuiltinFD) ||
6734 CGF.
CurFn->getAttributes().hasFnAttr(NoBuiltins);
6738 if (CGF.
CurFn->getName() != FDInlineName &&
6741 llvm::Function *Fn = llvm::cast<llvm::Function>(CalleePtr);
6742 llvm::Module *M = Fn->getParent();
6743 llvm::Function *Clone = M->getFunction(FDInlineName);
6745 Clone = llvm::Function::Create(Fn->getFunctionType(),
6746 llvm::GlobalValue::InternalLinkage,
6747 Fn->getAddressSpace(), FDInlineName, M);
6748 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
6759 else if (!IsPredefinedLibFunction || !HasAttributeNoBuiltin)
6765 FD->
hasAttr<CUDAGlobalAttr>())
6773 if (DeviceKernelAttr::isOpenCLSpelling(FD->
getAttr<DeviceKernelAttr>()))
6786 auto ConvertFuncrefToPtr = [&](llvm::Value *CalleePtr) -> llvm::Value * {
6787 if (
auto *TET = dyn_cast<llvm::TargetExtType>(CalleePtr->getType());
6788 TET && TET->getName() ==
"wasm.funcref") {
6789 llvm::Function *ToPtr =
6790 CGM.getIntrinsic(llvm::Intrinsic::wasm_funcref_to_ptr);
6791 return Builder.CreateCall(ToPtr, {CalleePtr});
6797 if (
auto ICE = dyn_cast<ImplicitCastExpr>(E)) {
6798 if (ICE->getCastKind() == CK_FunctionToPointerDecay ||
6799 ICE->getCastKind() == CK_BuiltinFnToFnPtr) {
6805 if (ICE->getCastKind() == CK_LValueToRValue) {
6806 const Expr *SubExpr = ICE->getSubExpr();
6808 std::pair<llvm::Value *, CGPointerAuthInfo>
Result =
6815 if (
const auto *VD =
6828 }
else if (
auto DRE = dyn_cast<DeclRefExpr>(E)) {
6829 if (
auto FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
6832 }
else if (
auto ME = dyn_cast<MemberExpr>(E)) {
6833 if (
auto FD = dyn_cast<FunctionDecl>(ME->getMemberDecl())) {
6839 }
else if (
auto NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
6843 }
else if (
auto PDE = dyn_cast<CXXPseudoDestructorExpr>(E)) {
6848 llvm::Value *calleePtr;
6860 if (
const auto *VD =
6866 CGCallee callee(calleeInfo, ConvertFuncrefToPtr(calleePtr), pointerAuth);
6882 assert(E->
getOpcode() == BO_Assign &&
"unexpected binary l-value");
6945 llvm::Value *
Result =
nullptr;
6948 if (
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
6963 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*
this,
6980 llvm_unreachable(
"bad evaluation kind");
6996 if (
CGM.getHLSLRuntime().emitGlobalResourceArray(*
this, E->
getRHS(), Slot))
7008 llvm::CallBase **CallOrInvoke) {
7016 "Can't have a scalar return unless the return type is a "
7029 &&
"binding l-value to type which needs a temporary");
7067 "Can't have a scalar return unless the return type is a "
7081 return CGM.getObjCRuntime().EmitIvarOffset(*
this,
Interface, Ivar);
7089 return Builder.CreateZExtOrTrunc(OffsetValue,
7094 llvm::Value *BaseValue,
7096 unsigned CVRQualifiers) {
7097 return CGM.getObjCRuntime().EmitObjCValueForIvar(*
this, ObjectTy, BaseValue,
7098 Ivar, CVRQualifiers);
7103 llvm::Value *BaseValue =
nullptr;
7114 ObjectTy = BaseExpr->
getType();
7136 llvm::CallBase **CallOrInvoke,
7141 "Call must have function pointer type!");
7143 const Decl *TargetDecl =
7146 assert((!isa_and_present<FunctionDecl>(TargetDecl) ||
7148 "trying to emit a call to an immediate function");
7158 if (
SanOpts.has(SanitizerKind::Function) &&
7161 if (llvm::Constant *PrefixSig =
7162 CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(
CGM)) {
7163 auto CheckOrdinal = SanitizerKind::SO_Function;
7164 auto CheckHandler = SanitizerHandler::FunctionTypeMismatch;
7168 llvm::Type *PrefixSigType = PrefixSig->getType();
7169 llvm::StructType *PrefixStructTy = llvm::StructType::get(
7170 CGM.getLLVMContext(), {PrefixSigType, Int32Ty},
true);
7172 llvm::Value *CalleePtr = Callee.getFunctionPointer();
7173 if (
CGM.getCodeGenOpts().PointerAuth.FunctionPointers) {
7176 Address(CalleePtr, CalleePtr->getType(),
7178 CalleePtr->getPointerAlignment(
CGM.getDataLayout())),
7179 Callee.getPointerAuthInfo(),
nullptr);
7180 CalleePtr =
Addr.emitRawPointer(*
this);
7192 llvm::Value *AlignedCalleePtr;
7193 if (
CGM.getTriple().isARM() ||
CGM.getTriple().isThumb()) {
7194 AlignedCalleePtr =
Builder.CreateIntrinsic(
7195 CalleePtr->getType(), llvm::Intrinsic::ptrmask,
7196 {CalleePtr, llvm::ConstantInt::getSigned(IntPtrTy, ~1)});
7198 AlignedCalleePtr = CalleePtr;
7201 llvm::Value *CalleePrefixStruct = AlignedCalleePtr;
7202 llvm::Value *CalleeSigPtr =
7203 Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 0);
7204 llvm::Value *CalleeSig =
7206 llvm::Value *CalleeSigMatch =
Builder.CreateICmpEQ(CalleeSig, PrefixSig);
7210 Builder.CreateCondBr(CalleeSigMatch, TypeCheck, Cont);
7213 llvm::Value *CalleeTypeHash =
Builder.CreateAlignedLoad(
7215 Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 1),
7217 llvm::Value *CalleeTypeHashMatch =
7218 Builder.CreateICmpEQ(CalleeTypeHash, TypeHash);
7221 EmitCheck(std::make_pair(CalleeTypeHashMatch, CheckOrdinal), CheckHandler,
7222 StaticData, {CalleePtr});
7231 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
7232 FD && DeviceKernelAttr::isOpenCLSpelling(FD->getAttr<DeviceKernelAttr>()))
7233 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FnType);
7237 if (
SanOpts.has(SanitizerKind::CFIICall) &&
7239 auto CheckOrdinal = SanitizerKind::SO_CFIICall;
7240 auto CheckHandler = SanitizerHandler::CFICheckFail;
7244 llvm::Metadata *MD =
7245 CGM.CreateMetadataIdentifierForFnType(
QualType(FnType, 0));
7247 llvm::Value *TypeId = llvm::MetadataAsValue::get(
getLLVMContext(), MD);
7249 llvm::Value *CalleePtr = Callee.getFunctionPointer();
7250 llvm::Value *TypeTest =
Builder.CreateCall(
7251 CGM.getIntrinsic(llvm::Intrinsic::type_test), {CalleePtr, TypeId});
7253 auto CrossDsoTypeId =
CGM.CreateCrossDsoCfiTypeId(MD);
7254 llvm::Constant *StaticData[] = {
7259 if (
CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
7263 EmitCheck(std::make_pair(TypeTest, CheckOrdinal), CheckHandler,
7264 StaticData, {CalleePtr, llvm::UndefValue::get(
IntPtrTy)});
7279 bool StaticOperator =
false;
7280 if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7281 if (OCE->isAssignmentOp())
7284 switch (OCE->getOperator()) {
7286 case OO_GreaterGreater:
7298 if (
const auto *MD =
7299 dyn_cast_if_present<CXXMethodDecl>(OCE->getCalleeDecl());
7300 MD && MD->isStatic())
7301 StaticOperator =
true;
7305 if (StaticOperator) {
7309 Arguments = drop_begin(Arguments, 1);
7311 EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), Arguments,
7318 *ResolvedFnInfo = &FnInfo;
7323 if (
CGM.getLangOpts().HIP && !
CGM.getLangOpts().CUDAIsDevice &&
7326 llvm::Value *Handle = Callee.getFunctionPointer();
7328 Address(Handle, Handle->getType(),
CGM.getPointerAlign()));
7329 Callee.setFunctionPointer(
Stub);
7336 if (
getLangOpts().OpenMPIsTargetDevice &&
CGM.getTriple().isGPU() &&
7340 while (CalleeExpr) {
7341 if ((DRE = dyn_cast<DeclRefExpr>(CalleeExpr)))
7343 if (
const auto *ME = dyn_cast<MemberExpr>(CalleeExpr))
7345 else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(CalleeExpr))
7351 const auto *VD = DRE ? dyn_cast<VarDecl>(DRE->
getDecl()) :
nullptr;
7352 if (VD && VD->hasAttr<OMPTargetIndirectCallAttr>()) {
7353 auto *FuncPtrTy = llvm::PointerType::get(
7354 CGM.getLLVMContext(),
CGM.getDataLayout().getProgramAddressSpace());
7355 llvm::Type *RtlFnArgs[] = {FuncPtrTy};
7356 llvm::FunctionCallee DeviceRtlFn =
CGM.CreateRuntimeFunction(
7357 llvm::FunctionType::get(FuncPtrTy, RtlFnArgs,
false),
7358 "__llvm_omp_indirect_call_lookup");
7359 llvm::Value *
Func = Callee.getFunctionPointer();
7360 llvm::Type *BackupTy =
Func->getType();
7364 Callee.setFunctionPointer(
Func);
7368 llvm::CallBase *LocalCallOrInvoke =
nullptr;
7372 if (
auto *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
7373 if (CalleeDecl->hasAttr<RestrictAttr>() ||
7374 CalleeDecl->hasAttr<MallocSpanAttr>() ||
7375 CalleeDecl->hasAttr<AllocSizeAttr>()) {
7377 if (
SanOpts.has(SanitizerKind::AllocToken)) {
7384 *CallOrInvoke = LocalCallOrInvoke;
7403 bool IsInBounds = !
getLangOpts().PointerOverflowDefined &&
7406 E, BaseAddr, OffsetV, MPT, IsInBounds, &BaseInfo, &TBAAInfo);
7408 return MakeAddrLValue(MemberAddr, MPT->getPointeeType(), BaseInfo, TBAAInfo);
7425 llvm_unreachable(
"bad evaluation kind");
7429 assert(Val->getType()->isFPOrFPVectorTy());
7434 llvm::MDNode *Node = MDHelper.createFPMath(Accuracy);
7440 llvm::Type *EltTy = Val->getType()->getScalarType();
7441 if (!EltTy->isFloatTy() && !EltTy->isHalfTy())
7445 !
CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) ||
7447 !
CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) {
7462 llvm::Type *EltTy = Val->getType()->getScalarType();
7463 if (!EltTy->isFloatTy() && !EltTy->isHalfTy())
7467 !
CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) ||
7469 !
CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) {
7484 struct LValueOrRValue {
7498 LValueOrRValue result;
7502 const Expr *semantic = *i;
7506 if (
const auto *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
7508 if (ov->isUnique()) {
7509 assert(ov != resultExpr &&
7510 "A unique OVE cannot be used as the result expression");
7518 if (ov == resultExpr && ov->
isPRValue() && !forLValue &&
7523 opaqueData = OVMA::bind(CGF, ov, LV);
7528 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
7531 if (ov == resultExpr) {
7539 opaques.push_back(opaqueData);
7543 }
else if (semantic == resultExpr) {
7575 std::tuple<LValue, QualType, llvm::SmallVector<llvm::Value *, 4>>, 16>
7577 llvm::IntegerType *IdxTy = llvm::IntegerType::get(
getLLVMContext(), 32);
7578 WorkList.push_back({Val, Val.
getType(), {llvm::ConstantInt::get(IdxTy, 0)}});
7580 while (!WorkList.empty()) {
7581 auto [LVal,
T, IdxList] = WorkList.pop_back_val();
7582 T =
T.getCanonicalType().getUnqualifiedType();
7583 if (
const auto *CAT = dyn_cast<ConstantArrayType>(
T)) {
7584 uint64_t Size = CAT->getZExtSize();
7585 for (int64_t I = Size - 1; I > -1; I--) {
7587 IdxListCopy.push_back(llvm::ConstantInt::get(IdxTy, I));
7588 WorkList.emplace_back(LVal, CAT->getElementType(), IdxListCopy);
7590 }
else if (
const auto *RT = dyn_cast<RecordType>(
T)) {
7592 assert(!
Record->isUnion() &&
"Union types not supported in flat cast.");
7597 std::tuple<LValue, QualType, llvm::SmallVector<llvm::Value *, 4>>, 16>
7606 "HLSL doesn't support multiple inheritance.");
7609 IdxListCopy.push_back(llvm::ConstantInt::get(
7611 ReverseList.emplace_back(LVal,
Base->getType(), IdxListCopy);
7620 bool createdGEP =
false;
7621 for (
auto *FD :
Record->fields()) {
7622 if (FD->isBitField()) {
7623 if (FD->isUnnamedBitField())
7627 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList,
7628 LLVMT, Align,
"gep");
7632 ReverseList.push_back({FieldLVal, FD->
getType(), {}});
7635 IdxListCopy.push_back(
7637 ReverseList.emplace_back(LVal, FD->getType(), IdxListCopy);
7641 std::reverse(ReverseList.begin(), ReverseList.end());
7642 llvm::append_range(WorkList, ReverseList);
7643 }
else if (
const auto *VT = dyn_cast<VectorType>(
T)) {
7646 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList, LLVMT,
7647 Align,
"vector.gep");
7649 for (
unsigned I = 0, E = VT->getNumElements(); I < E; I++) {
7650 llvm::Constant *Idx = llvm::ConstantInt::get(IdxTy, I);
7654 AccessList.emplace_back(LV);
7656 }
else if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T)) {
7664 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList, LLVMT,
7665 Align,
"matrix.gep");
7668 unsigned NumRows = MT->getNumRows();
7669 unsigned NumCols = MT->getNumColumns();
7671 llvm::MatrixBuilder MB(
Builder);
7672 for (
unsigned Row = 0; Row < MT->getNumRows(); Row++) {
7673 for (
unsigned Col = 0; Col < MT->getNumColumns(); Col++) {
7674 llvm::Value *RowIdx = llvm::ConstantInt::get(IdxTy, Row);
7675 llvm::Value *ColIdx = llvm::ConstantInt::get(IdxTy, Col);
7676 llvm::Value *Idx = MB.CreateIndex(RowIdx, ColIdx, NumRows, NumCols,
7681 AccessList.emplace_back(LV);
7685 if (!IdxList.empty()) {
7688 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList,
7689 LLVMT, Align,
"gep");
7692 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 bool getRangeForType(CodeGenFunction &CGF, QualType Ty, llvm::APInt &Min, llvm::APInt &End, bool StrictEnums, bool StrictBool, bool IsBool)
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 Address emitRawAddrOfFieldStorage(CodeGenFunction &CGF, Address base, const FieldDecl *field, bool IsInBounds)
Drill down to the storage of a field without walking into reference types, and without respect for po...
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 llvm::Value * convertSizedByBoundToElementCount(CodeGenFunction &CGF, llvm::Value *BoundsVal, QualType PointeeTy, bool CountSigned)
Convert a '__sized_by' byte-count bound to an element-count bound so it can be compared against an el...
static CheckRecoverableKind getRecoverableKind(SanitizerKind::SanitizerOrdinal Ordinal)
static bool RecordContainsField(const RecordDecl *RD, const FieldDecl *Field)
Returns true if Field is reachable from RD either as a direct field or through a chain of nested reco...
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 emitAddrOfFieldStorage(CodeGenFunction &CGF, Address base, const FieldDecl *field, bool IsInBounds)
Drill down to the storage of a field without walking into reference types, wrapping the address in an...
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 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 CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx, CharUnits eltSize)
static void pushTemporaryCleanup(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *e, Address referenceTemporary)
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 Address emitAddrOfZeroSizeField(CIRGenFunction &cgf, Address base, const FieldDecl *field)
Get the address of a zero-sized field within a record.
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Record Record
Defines AST-level helper utilities for matrix types.
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.
static bool isPFPField(const FieldDecl *Field)
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
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 binding in a decomposition declaration.
Expr * getBinding() const
Get the expression to which this declaration is bound.
DecompositionDecl * getDecomposedDecl() const
Get the decomposition declaration that this binding represents a decomposition of.
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.
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
Returns Quantity as a valid llvm::Align or std::nullopt, Beware llvm::MaybeAlign assumes power of two...
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits 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)
Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Construct a CharUnits quantity of zero.
@ None
Trap Messages are omitted.
@ Detailed
Trap Message includes more context (e.g.
@ Strict
In-memory bool values are assumed to be 0 or 1, and any other value is UB.
bool isOptimizedBuild() const
Are we building at -O1 or higher?
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 bool HasThisReturn(GlobalDecl GD) const
Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...
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 canCallMismatchedFunctionType() const
Returns true if the target allows calling a function through a pointer with a different signature tha...
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.
std::optional< LValue > emitGlobalResourceArrayAsLValue(CodeGenFunction &CGF, const VarDecl *ArrayDecl)
RawAddress createBufferMatrixTempAddress(const LValue &LV, CodeGenFunction &CGF)
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...
llvm::StructType * getLLVMType() const
Return the "complete object" LLVM type associated with this record.
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)
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)
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.
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID, bool EnsureInsertPoint=true)
Emit a call to trap or debugtrap.
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)
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
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.
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.
RawAddress CreateIRTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateIRTempWithoutCast - Create a temporary IR object of the given type, with appropriate alignment.
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.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
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,...
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)
Address EmitAddressOfPFPField(Address RecordPtr, const PFPField &Field)
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)
LValue EmitOMPCapturedBindingLValue(const BindingDecl *BD)
Emit an LValue for a structured binding captured in an OpenMP region.
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)
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
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,...
const FunctionDecl * getCurrentFunctionDecl() const
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)
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 EmitTrapCallAndMakeUnreachable()
Emit a call to '@llvm.trap()' and clear the current insert point.
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
LValue EmitMatrixElementExpr(const MatrixElementExpr *E)
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...
bool hasLabelBeenSeenInCurrentScope() const
Return true if a label was seen in the current scope.
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.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
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 * performAddrSpaceCast(llvm::Constant *Src, llvm::Type *DestTy)
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.
llvm::Constant * tryEmitConstantExpr(const ConstantExpr *CE)
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,...
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
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
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.
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
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()
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
const Expr * getBase() const
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 * 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...
ExtVectorType - Extended vector type.
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.
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.
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.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
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.
void getEncodedElementAccess(SmallVectorImpl< uint32_t > &Elts) const
getEncodedElementAccess - Encode the elements accessed into an llvm aggregate Constant of ConstantInt...
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.
RecordDecl * getDefinitionOrSelf() const
Scope - A scope is a transient data structure that is used while parsing the program.
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.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
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
bool isAAPCS(const TargetInfo &TargetInfo)
Helper method to check if the underlying ABI is AAPCS.
QualType getFixedSizeElementType(const ASTContext &Ctx, const VariableArrayType *VLA)
Strip off the variably-modified array types wrapping VLA and return the first element type that has a...
bool onlyHasInlineBuiltinDeclaration(const FunctionDecl *FD)
Detect the unusual situation where an inline version of a builtin is shadowed by a non-inline version...
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.
Top level wrappers for InstallAPI frontend operations.
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.
bool isMatrixRowMajor(const LangOptions &LangOpts, QualType T)
Returns true if matrices of T should be laid out in row-major order.
@ 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
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
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,...
int32_t uint32_t uint32_t __packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 __packed_splat4 uint16_t
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
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