43#include "llvm/ADT/STLExtras.h"
44#include "llvm/ADT/ScopeExit.h"
45#include "llvm/ADT/StringExtras.h"
46#include "llvm/IR/Constants.h"
47#include "llvm/IR/DataLayout.h"
48#include "llvm/IR/Intrinsics.h"
49#include "llvm/IR/IntrinsicsWebAssembly.h"
50#include "llvm/IR/LLVMContext.h"
51#include "llvm/IR/MDBuilder.h"
52#include "llvm/IR/MatrixBuilder.h"
53#include "llvm/Support/ConvertUTF.h"
54#include "llvm/Support/Endian.h"
55#include "llvm/Support/MathExtras.h"
56#include "llvm/Support/Path.h"
57#include "llvm/Support/xxhash.h"
58#include "llvm/Transforms/Utils/SanitizerStats.h"
71 "ubsan-guard-checks", llvm::cl::Optional,
72 llvm::cl::desc(
"Guard UBSAN checks with `llvm.allow.ubsan.check()`."));
98#define SANITIZER_CHECK(Enum, Name, Version, Msg) \
99 case SanitizerHandler::Enum: \
102#undef SANITIZER_CHECK
104 llvm_unreachable(
"unhandled switch case");
112 llvm::Value *ArraySize) {
114 auto Alloca =
Builder.CreateStructuredAlloca(Ty, Name);
125 llvm::Value *ArraySize) {
135 llvm::IRBuilderBase::InsertPointGuard IPG(Builder);
150 llvm::Value *ArraySize,
154 *AllocaAddr = Alloca;
155 return MaybeCastStackAddressSpace(Alloca, DestLangAS, ArraySize);
163 llvm::Value *ArraySize) {
164 llvm::AllocaInst *Alloca;
166 Alloca =
Builder.CreateAlloca(Ty, ArraySize, Name);
169 new llvm::AllocaInst(Ty,
CGM.getDataLayout().getAllocaAddrSpace(),
171 if (
SanOpts.Mask & SanitizerKind::Address) {
172 Alloca->addAnnotationMetadata({
"alloca_name_altered", Name.str()});
175 Allocas->Add(Alloca);
212 auto *ArrayElementTy = ArrayTy->getElementType();
213 auto ArrayElements = ArrayTy->getNumElements();
216 ArrayElementTy = VectorTy->getElementType();
217 ArrayElements *= VectorTy->getNumElements();
219 auto *VectorTy = llvm::FixedVectorType::get(ArrayElementTy, ArrayElements);
242 PGO->setCurrentStmt(E);
245 return CGM.getCXXABI().EmitMemberPointerIsNotNull(*
this, MemPtr, MPT);
268 if (
const auto *CondOp = dyn_cast<AbstractConditionalOperator>(
291 if (!ignoreResult && aggSlot.
isIgnored())
296 llvm_unreachable(
"bad evaluation kind");
338 llvm_unreachable(
"bad evaluation kind");
361 llvm_unreachable(
"bad evaluation kind");
401 bool Precise = isa_and_nonnull<VarDecl>(VD) &&
402 VD->
hasAttr<ObjCPreciseLifetimeAttr>();
423 llvm_unreachable(
"temporary cannot have dynamic storage duration");
425 llvm_unreachable(
"unknown storage duration");
435 if (
const auto *ClassDecl =
439 ReferenceTemporaryDtor = ClassDecl->getDestructor();
441 if (!ReferenceTemporaryDtor)
444 llvm::FunctionCallee CleanupFn;
445 llvm::Constant *CleanupArg;
451 CleanupArg = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
468 llvm_unreachable(
"temporary cannot have dynamic storage duration");
490 auto *GV =
new llvm::GlobalVariable(
492 llvm::GlobalValue::PrivateLinkage,
Init,
".ref.tmp",
nullptr,
493 llvm::GlobalValue::NotThreadLocal,
497 llvm::Constant *
C = GV;
504 return RawAddress(
C, GV->getValueType(), alignment);
513 llvm_unreachable(
"temporary can't have dynamic storage duration");
515 llvm_unreachable(
"unknown storage duration");
524 "Reference should never be pseudo-strong!");
532 if (
auto *Var = dyn_cast<llvm::GlobalVariable>(
Object.getPointer())) {
542 if (Var->hasInitializer())
545 Var->setInitializer(
CGM.EmitNullConstant(E->
getType()));
551 default: llvm_unreachable(
"expected scalar or aggregate expression");
574 for (
const auto &Ignored : CommaLHSs)
577 if (
const auto *opaque = dyn_cast<OpaqueValueExpr>(E)) {
578 if (opaque->getType()->isRecordType()) {
579 assert(Adjustments.empty());
587 if (
auto *Var = dyn_cast<llvm::GlobalVariable>(
588 Object.getPointer()->stripPointerCasts())) {
594 if (!Var->hasInitializer()) {
595 Var->setInitializer(
CGM.EmitNullConstant(E->
getType()));
616 if (!ShouldEmitLifetimeMarkers)
627 CGBuilderTy::InsertPoint OldIP;
629 ((!
SanOpts.has(SanitizerKind::HWAddress) &&
630 !
SanOpts.has(SanitizerKind::Memory) &&
631 !
SanOpts.has(SanitizerKind::MemtagStack) &&
632 !
CGM.getCodeGenOpts().SanitizeAddressUseAfterScope) ||
634 OldConditional = OutermostConditional;
635 OutermostConditional =
nullptr;
639 Builder.restoreIP(CGBuilderTy::InsertPoint(
640 Block, llvm::BasicBlock::iterator(
Block->back())));
647 if (OldConditional) {
648 OutermostConditional = OldConditional;
665 switch (Adjustment.Kind) {
669 Adjustment.DerivedToBase.BasePath->path_begin(),
670 Adjustment.DerivedToBase.BasePath->path_end(),
678 "materialized temporary field is not a simple lvalue");
686 E,
Object, Ptr, Adjustment.Ptr.MPT,
true);
719 const llvm::Constant *Elts) {
727 Builder.CreateMul(Ptr, Builder.getInt64(0xbf58476d1ce4e5b9u));
729 Builder.CreateXor(A0, Builder.CreateLShr(A0, Builder.getInt64(31)));
730 return Builder.CreateXor(Acc, A1);
747 return SanOpts.has(SanitizerKind::Null) ||
748 SanOpts.has(SanitizerKind::Alignment) ||
749 SanOpts.has(SanitizerKind::ObjectSize) ||
750 SanOpts.has(SanitizerKind::Vptr);
757 llvm::Value *ArraySize) {
764 if (Ptr->getType()->getPointerAddressSpace())
775 auto PtrToAlloca = dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCasts());
777 llvm::Value *IsNonNull =
nullptr;
778 bool IsGuaranteedNonNull =
779 SkippedChecks.
has(SanitizerKind::Null) || PtrToAlloca;
781 llvm::BasicBlock *Done =
nullptr;
782 bool DoneViaNullSanitize =
false;
785 auto CheckHandler = SanitizerHandler::TypeMismatch;
787 {SanitizerKind::SO_Null,
788 SanitizerKind::SO_ObjectSize,
789 SanitizerKind::SO_Alignment},
797 if ((
SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
798 !IsGuaranteedNonNull) {
800 IsNonNull =
Builder.CreateIsNotNull(Ptr);
804 IsGuaranteedNonNull = IsNonNull ==
True;
807 if (!IsGuaranteedNonNull) {
808 if (AllowNullPointers) {
812 DoneViaNullSanitize =
true;
814 Builder.CreateCondBr(IsNonNull, Rest, Done);
817 Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::SO_Null));
822 if (
SanOpts.has(SanitizerKind::ObjectSize) &&
823 !SkippedChecks.
has(SanitizerKind::ObjectSize) &&
825 uint64_t TySize =
CGM.getMinimumObjectSize(Ty).getQuantity();
826 llvm::Value *Size = llvm::ConstantInt::get(
IntPtrTy, TySize);
828 Size =
Builder.CreateMul(Size, ArraySize);
831 llvm::Constant *ConstantSize = dyn_cast<llvm::Constant>(Size);
832 if (!ConstantSize || !ConstantSize->isNullValue()) {
839 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::objectsize, Tys);
841 llvm::Value *NullIsUnknown =
Builder.getFalse();
842 llvm::Value *Dynamic =
Builder.getFalse();
843 llvm::Value *LargeEnough =
Builder.CreateICmpUGE(
844 Builder.CreateCall(F, {Ptr, Min, NullIsUnknown, Dynamic}), Size);
846 std::make_pair(LargeEnough, SanitizerKind::SO_ObjectSize));
850 llvm::MaybeAlign AlignVal;
851 llvm::Value *PtrAsInt =
nullptr;
853 if (
SanOpts.has(SanitizerKind::Alignment) &&
854 !SkippedChecks.
has(SanitizerKind::Alignment)) {
857 AlignVal =
CGM.getNaturalTypeAlignment(Ty,
nullptr,
nullptr,
862 if (AlignVal && *AlignVal > llvm::Align(1) &&
863 (!PtrToAlloca || PtrToAlloca->getAlign() < *AlignVal)) {
865 llvm::Value *Align =
Builder.CreateAnd(
866 PtrAsInt, llvm::ConstantInt::get(
IntPtrTy, AlignVal->value() - 1));
867 llvm::Value *Aligned =
871 std::make_pair(Aligned, SanitizerKind::SO_Alignment));
875 if (Checks.size() > 0) {
876 llvm::Constant *StaticData[] = {
878 llvm::ConstantInt::get(
Int8Ty, AlignVal ? llvm::Log2(*AlignVal) : 1),
879 llvm::ConstantInt::get(
Int8Ty, TCK)};
880 EmitCheck(Checks, CheckHandler, StaticData, PtrAsInt ? PtrAsInt : Ptr);
892 if (
SanOpts.has(SanitizerKind::Vptr) &&
895 SanitizerHandler::DynamicTypeCacheMiss);
899 if (!IsGuaranteedNonNull) {
901 IsNonNull =
Builder.CreateIsNotNull(Ptr);
905 Builder.CreateCondBr(IsNonNull, VptrNotNull, Done);
911 llvm::raw_svector_ostream Out(MangledName);
916 if (!
CGM.getContext().getNoSanitizeList().containsType(SanitizerKind::Vptr,
919 llvm::Value *TypeHash =
920 llvm::ConstantInt::get(
Int64Ty, xxh3_64bits(Out.str()));
934 const int CacheSize = 128;
935 llvm::Type *HashTable = llvm::ArrayType::get(
IntPtrTy, CacheSize);
936 llvm::Value *
Cache =
CGM.CreateRuntimeVariable(HashTable,
937 "__ubsan_vptr_type_cache");
938 llvm::Value *Slot =
Builder.CreateAnd(Hash,
941 llvm::Value *Indices[] = {
Builder.getInt32(0), Slot };
942 llvm::Value *CacheVal =
Builder.CreateAlignedLoad(
950 llvm::Value *EqualHash =
Builder.CreateICmpEQ(CacheVal, Hash);
951 llvm::Constant *StaticData[] = {
955 llvm::ConstantInt::get(
Int8Ty, TCK)
957 llvm::Value *DynamicData[] = { Ptr, Hash };
958 EmitCheck(std::make_pair(EqualHash, SanitizerKind::SO_Vptr),
959 SanitizerHandler::DynamicTypeCacheMiss, StaticData,
967 {DoneViaNullSanitize ? SanitizerKind::SO_Null : SanitizerKind::SO_Vptr},
968 DoneViaNullSanitize ? SanitizerHandler::TypeMismatch
969 : SanitizerHandler::DynamicTypeCacheMiss);
978 uint64_t EltSize =
C.getTypeSizeInChars(EltTy).getQuantity();
986 auto *ParamDecl = dyn_cast<ParmVarDecl>(ArrayDeclRef->getDecl());
990 auto *POSAttr = ParamDecl->getAttr<PassObjectSizeAttr>();
995 int POSType = POSAttr->getType();
996 if (POSType != 0 && POSType != 1)
1000 auto PassedSizeIt = SizeArguments.find(ParamDecl);
1001 if (PassedSizeIt == SizeArguments.end())
1005 assert(LocalDeclMap.count(PassedSizeDecl) &&
"Passed size not loadable");
1006 Address AddrOfSize = LocalDeclMap.find(PassedSizeDecl)->second;
1009 llvm::Value *SizeOfElement =
1010 llvm::ConstantInt::get(SizeInBytes->getType(), EltSize);
1011 return Builder.CreateUDiv(SizeInBytes, SizeOfElement);
1020 StrictFlexArraysLevel) {
1023 IndexedType =
Base->getType();
1024 return CGF.
Builder.getInt32(VT->getNumElements());
1029 if (
const auto *CE = dyn_cast<CastExpr>(
Base)) {
1030 if (CE->getCastKind() == CK_ArrayToPointerDecay &&
1031 !CE->getSubExpr()->isFlexibleArrayMemberLike(CGF.
getContext(),
1032 StrictFlexArraysLevel)) {
1035 IndexedType = CE->getSubExpr()->getType();
1037 if (
const auto *CAT = dyn_cast<ConstantArrayType>(AT))
1038 return CGF.
Builder.getInt(CAT->getSize());
1040 if (
const auto *VAT = dyn_cast<VariableArrayType>(AT))
1048 QualType EltTy{
Base->getType()->getPointeeOrArrayElementType(), 0};
1050 IndexedType =
Base->getType();
1091class StructAccessBase
1092 :
public ConstStmtVisitor<StructAccessBase, const Expr *> {
1096 const FieldDecl *CountDecl;
1101 bool IsExpectedRecordDecl(
const Expr *E)
const {
1110 StructAccessBase(
const FieldDecl *CountDecl) : CountDecl(CountDecl) {}
1129 const Expr *Visit(
const Expr *E) {
1130 return ConstStmtVisitor<StructAccessBase, const Expr *>::Visit(E);
1133 const Expr *VisitStmt(
const Stmt *S) {
return nullptr; }
1148 const Expr *VisitDeclRefExpr(
const DeclRefExpr *E) {
1149 return IsExpectedRecordDecl(E) ? E :
nullptr;
1151 const Expr *VisitMemberExpr(
const MemberExpr *E) {
1152 if (IsExpectedRecordDecl(E) && E->
isArrow())
1154 const Expr *Res = Visit(E->
getBase());
1155 return !Res && IsExpectedRecordDecl(E) ? E : Res;
1157 const Expr *VisitCompoundLiteralExpr(
const CompoundLiteralExpr *E) {
1158 return IsExpectedRecordDecl(E) ? E :
nullptr;
1160 const Expr *VisitCallExpr(
const CallExpr *E) {
1161 return IsExpectedRecordDecl(E) ? E :
nullptr;
1164 const Expr *VisitArraySubscriptExpr(
const ArraySubscriptExpr *E) {
1165 if (IsExpectedRecordDecl(E))
1169 const Expr *VisitCastExpr(
const CastExpr *E) {
1171 return IsExpectedRecordDecl(E) ? E :
nullptr;
1174 const Expr *VisitParenExpr(
const ParenExpr *E) {
1177 const Expr *VisitUnaryAddrOf(
const UnaryOperator *E) {
1180 const Expr *VisitUnaryDeref(
const UnaryOperator *E) {
1193 int64_t FieldNo = -1;
1202 Indices.emplace_back(CGF.
Builder.getInt32(FieldNo));
1211 Indices.emplace_back(CGF.
Builder.getInt32(FieldNo));
1227 const Expr *StructBase = StructAccessBase(CountDecl).Visit(
Base);
1239 llvm::Value *Res =
nullptr;
1244 Res =
Addr.emitRawPointer(*
this);
1245 }
else if (StructBase->
isLValue()) {
1248 Res =
Addr.emitRawPointer(*
this);
1255 if (Indices.empty())
1258 Indices.push_back(
Builder.getInt32(0));
1282 const Expr *ArrayExprBase,
1283 llvm::Value *IndexVal,
QualType IndexType,
1285 assert(
SanOpts.has(SanitizerKind::ArrayBounds) &&
1286 "should not be called unless adding bounds checks");
1291 *
this, ArrayExprBase, ArrayExprBaseType, StrictFlexArraysLevel);
1294 BoundsVal,
getContext().getSizeType(), Accessed);
1299 llvm::Value *IndexVal,
1301 llvm::Value *BoundsVal,
1302 QualType BoundsType,
bool Accessed) {
1306 auto CheckKind = SanitizerKind::SO_ArrayBounds;
1307 auto CheckHandler = SanitizerHandler::OutOfBounds;
1319 llvm::Value *IndexInst =
Builder.CreateIntCast(IndexVal, Ty, IndexSigned);
1320 llvm::Value *BoundsInst =
Builder.CreateIntCast(BoundsVal, Ty,
false);
1322 llvm::Constant *StaticData[] = {
1328 llvm::Value *Check = Accessed ?
Builder.CreateICmpULT(IndexInst, BoundsInst)
1329 :
Builder.CreateICmpULE(IndexInst, BoundsInst);
1334 BoundsVal, llvm::ConstantInt::get(BoundsVal->getType(), 0));
1338 EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData,
1348 auto *TypeNameMD = MDB.createString(ATMD->TypeName);
1349 auto *ContainsPtrC =
Builder.getInt1(ATMD->ContainsPointer);
1350 auto *ContainsPtrMD = MDB.createConstant(ContainsPtrC);
1353 return llvm::MDNode::get(
CGM.getLLVMContext(), {TypeNameMD, ContainsPtrMD});
1357 assert(
SanOpts.has(SanitizerKind::AllocToken) &&
1358 "Only needed with -fsanitize=alloc-token");
1359 CB->setMetadata(llvm::LLVMContext::MD_alloc_token,
1371 assert(
SanOpts.has(SanitizerKind::AllocToken) &&
1372 "Only needed with -fsanitize=alloc-token");
1374 CB->setMetadata(llvm::LLVMContext::MD_alloc_token, MDN);
1379 bool isInc,
bool isPre) {
1382 llvm::Value *NextVal;
1384 uint64_t AmountVal = isInc ? 1 : -1;
1385 NextVal = llvm::ConstantInt::get(InVal.first->getType(), AmountVal,
true);
1388 NextVal =
Builder.CreateAdd(InVal.first, NextVal, isInc ?
"inc" :
"dec");
1391 llvm::APFloat FVal(
getContext().getFloatTypeSemantics(ElemTy), 1);
1397 NextVal =
Builder.CreateFAdd(InVal.first, NextVal, isInc ?
"inc" :
"dec");
1405 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*
this,
1410 return isPre ? IncVal : InVal;
1420 DI->EmitExplicitCastType(E->
getType());
1431 if (
auto *constantIdx = dyn_cast<llvm::ConstantInt>(idx)) {
1432 CharUnits offset = constantIdx->getZExtValue() * eltSize;
1446 assert(BO->
isAdditiveOp() &&
"Expect an addition or subtraction.");
1449 bool isSubtraction = BO->
getOpcode() == BO_Sub;
1452 llvm::Value *
index =
nullptr;
1456 std::swap(pointerOperand, indexOperand);
1468 BO, pointerOperand, pointer, indexOperand,
index, isSubtraction);
1475 nullptr, IsKnownNonNull);
1488 if (
const CastExpr *CE = dyn_cast<CastExpr>(E)) {
1489 if (
const auto *ECE = dyn_cast<ExplicitCastExpr>(CE))
1492 switch (CE->getCastKind()) {
1496 case CK_AddressSpaceConversion:
1497 if (
auto PtrTy = CE->getSubExpr()->getType()->getAs<
PointerType>()) {
1498 if (PtrTy->getPointeeType()->isVoidType())
1504 CE->getSubExpr(), &InnerBaseInfo, &InnerTBAAInfo, IsKnownNonNull);
1505 if (BaseInfo) *BaseInfo = InnerBaseInfo;
1506 if (TBAAInfo) *TBAAInfo = InnerTBAAInfo;
1512 E->
getType(), &TargetTypeBaseInfo, &TargetTypeTBAAInfo);
1520 BaseInfo->mergeForCast(TargetTypeBaseInfo);
1521 Addr.setAlignment(Align);
1525 if (CGF.
SanOpts.
has(SanitizerKind::CFIUnrelatedCast) &&
1526 CE->getCastKind() == CK_BitCast) {
1534 llvm::Type *ElemTy =
1536 Addr =
Addr.withElementType(ElemTy);
1537 if (CE->getCastKind() == CK_AddressSpaceConversion)
1547 case CK_ArrayToPointerDecay:
1551 case CK_UncheckedDerivedToBase:
1552 case CK_DerivedToBase: {
1559 CE->getSubExpr(), BaseInfo,
nullptr,
1561 CE->getCastKind() == CK_UncheckedDerivedToBase));
1562 auto Derived = CE->getSubExpr()->
getType()->getPointeeCXXRecordDecl();
1564 Addr, Derived, CE->path_begin(), CE->path_end(),
1577 if (UO->getOpcode() == UO_AddrOf) {
1578 LValue LV = CGF.
EmitLValue(UO->getSubExpr(), IsKnownNonNull);
1579 if (BaseInfo) *BaseInfo = LV.getBaseInfo();
1580 if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
1581 return LV.getAddress();
1586 if (
auto *
Call = dyn_cast<CallExpr>(E)) {
1587 switch (
Call->getBuiltinCallee()) {
1590 case Builtin::BIaddressof:
1591 case Builtin::BI__addressof:
1592 case Builtin::BI__builtin_addressof: {
1594 if (BaseInfo) *BaseInfo = LV.getBaseInfo();
1595 if (TBAAInfo) *TBAAInfo = LV.getTBAAInfo();
1596 return LV.getAddress();
1602 if (
auto *BO = dyn_cast<BinaryOperator>(E)) {
1603 if (BO->isAdditiveOp())
1612 true, BaseInfo, TBAAInfo, IsKnownNonNull);
1622 if (IsKnownNonNull && !
Addr.isKnownNonNull())
1623 Addr.setKnownNonNull();
1630 return CGM.getCXXABI().EmitMemberPointerIsNotNull(*
this,
V, MPT);
1631 return Builder.CreateICmpNE(
V, llvm::Constant::getNullValue(
V->getType()));
1642 llvm::Value *
U = llvm::UndefValue::get(EltTy);
1657 llvm_unreachable(
"bad evaluation kind");
1682 if (
const auto *CE = dyn_cast<CastExpr>(
Base)) {
1683 Base = CE->getSubExpr();
1684 }
else if (
const auto *PE = dyn_cast<ParenExpr>(
Base)) {
1685 Base = PE->getSubExpr();
1686 }
else if (
const auto *UO = dyn_cast<UnaryOperator>(
Base)) {
1687 if (UO->getOpcode() == UO_Extension)
1688 Base = UO->getSubExpr();
1706 if (
const auto *ME = dyn_cast<MemberExpr>(E)) {
1709 SkippedChecks.
set(SanitizerKind::Alignment,
true);
1711 SkippedChecks.
set(SanitizerKind::Null,
true);
1738 CGM.runWithSufficientStackSpace(
1739 E->
getExprLoc(), [&] { LV = EmitLValueHelper(E, IsKnownNonNull); });
1746LValue CodeGenFunction::EmitLValueHelper(
const Expr *E,
1752 case Expr::ObjCPropertyRefExprClass:
1753 llvm_unreachable(
"cannot emit a property reference directly");
1755 case Expr::ObjCSelectorExprClass:
1757 case Expr::ObjCIsaExprClass:
1759 case Expr::BinaryOperatorClass:
1761 case Expr::CompoundAssignOperatorClass: {
1764 Ty = AT->getValueType();
1769 case Expr::CallExprClass:
1770 case Expr::CXXMemberCallExprClass:
1771 case Expr::CXXOperatorCallExprClass:
1772 case Expr::UserDefinedLiteralClass:
1774 case Expr::CXXRewrittenBinaryOperatorClass:
1777 case Expr::VAArgExprClass:
1779 case Expr::DeclRefExprClass:
1781 case Expr::ConstantExprClass: {
1787 case Expr::ParenExprClass:
1789 case Expr::GenericSelectionExprClass:
1792 case Expr::PredefinedExprClass:
1794 case Expr::StringLiteralClass:
1796 case Expr::ObjCEncodeExprClass:
1798 case Expr::PseudoObjectExprClass:
1800 case Expr::InitListExprClass:
1802 case Expr::CXXTemporaryObjectExprClass:
1803 case Expr::CXXConstructExprClass:
1805 case Expr::CXXBindTemporaryExprClass:
1807 case Expr::CXXUuidofExprClass:
1809 case Expr::LambdaExprClass:
1812 case Expr::ExprWithCleanupsClass: {
1814 RunCleanupsScope
Scope(*
this);
1815 LValue LV =
EmitLValue(cleanups->getSubExpr(), IsKnownNonNull);
1816 if (LV.isSimple()) {
1820 llvm::Value *
V =
Addr.getBasePointer();
1821 Scope.ForceCleanup({&
V});
1822 Addr.replaceBasePointer(
V);
1824 LV.getBaseInfo(), LV.getTBAAInfo());
1831 case Expr::CXXDefaultArgExprClass: {
1834 return EmitLValue(DAE->getExpr(), IsKnownNonNull);
1836 case Expr::CXXDefaultInitExprClass: {
1839 return EmitLValue(DIE->getExpr(), IsKnownNonNull);
1841 case Expr::CXXTypeidExprClass:
1844 case Expr::ObjCMessageExprClass:
1846 case Expr::ObjCIvarRefExprClass:
1848 case Expr::StmtExprClass:
1850 case Expr::UnaryOperatorClass:
1852 case Expr::ArraySubscriptExprClass:
1854 case Expr::MatrixSingleSubscriptExprClass:
1856 case Expr::MatrixSubscriptExprClass:
1858 case Expr::ArraySectionExprClass:
1860 case Expr::ExtVectorElementExprClass:
1862 case Expr::MatrixElementExprClass:
1864 case Expr::CXXThisExprClass:
1866 case Expr::MemberExprClass:
1868 case Expr::CompoundLiteralExprClass:
1870 case Expr::ConditionalOperatorClass:
1872 case Expr::BinaryConditionalOperatorClass:
1874 case Expr::ChooseExprClass:
1876 case Expr::OpaqueValueExprClass:
1878 case Expr::SubstNonTypeTemplateParmExprClass:
1881 case Expr::ImplicitCastExprClass:
1882 case Expr::CStyleCastExprClass:
1883 case Expr::CXXFunctionalCastExprClass:
1884 case Expr::CXXStaticCastExprClass:
1885 case Expr::CXXDynamicCastExprClass:
1886 case Expr::CXXReinterpretCastExprClass:
1887 case Expr::CXXConstCastExprClass:
1888 case Expr::CXXAddrspaceCastExprClass:
1889 case Expr::ObjCBridgedCastExprClass:
1892 case Expr::MaterializeTemporaryExprClass:
1895 case Expr::CoawaitExprClass:
1897 case Expr::CoyieldExprClass:
1899 case Expr::PackIndexingExprClass:
1901 case Expr::HLSLOutArgExprClass:
1902 llvm_unreachable(
"cannot emit a HLSL out argument directly");
1909 assert(
type.isCanonical());
1910 assert(!
type->isReferenceType());
1918 if (
const auto *RT = dyn_cast<RecordType>(
type))
1919 if (
const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
1921 if (RD->hasMutableFields() || !RD->isTrivial())
1943 if (
const auto *ref = dyn_cast<ReferenceType>(
type)) {
1967 }
else if (
const auto *var = dyn_cast<VarDecl>(
Value)) {
1977 bool resultIsReference;
1983 resultIsReference =
false;
1989 resultIsReference =
true;
2010 auto *MD = dyn_cast_or_null<CXXMethodDecl>(
CurCodeDecl);
2011 if (
isLambdaMethod(MD) && MD->getOverloadedOperator() == OO_Call) {
2014 if (
const VarDecl *VD = dyn_cast<const VarDecl>(D)) {
2015 if (!VD->hasAttr<CUDADeviceAttr>()) {
2038 if (resultIsReference)
2065 assert(
Constant &&
"not a constant");
2088 llvm::APInt &End,
bool StrictEnums,
bool StrictBool,
2091 bool IsRegularCPlusPlusEnum =
2092 CGF.
getLangOpts().CPlusPlus && StrictEnums && ED && !ED->isFixed();
2093 if (!IsBool && !IsRegularCPlusPlusEnum)
2102 ED->getValueRange(End,
Min);
2107llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
2108 llvm::APInt
Min, End;
2110 bool StrictBoolEnabled =
CGM.getCodeGenOpts().getLoadBoolFromMem() ==
2113 CGM.getCodeGenOpts().StrictEnums,
2114 StrictBoolEnabled, IsBool))
2118 return MDHelper.createRange(
Min, End);
2126 }
else if (
CGM.getCodeGenOpts().isOptimizedBuild()) {
2127 if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty)) {
2128 Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
2129 Load->setMetadata(llvm::LLVMContext::MD_noundef,
2130 llvm::MDNode::get(
CGM.getLLVMContext(), {}));
2137 bool HasBoolCheck =
SanOpts.has(SanitizerKind::Bool);
2138 bool HasEnumCheck =
SanOpts.has(SanitizerKind::Enum);
2139 if (!HasBoolCheck && !HasEnumCheck)
2144 bool NeedsBoolCheck = HasBoolCheck && IsBool;
2146 if (!NeedsBoolCheck && !NeedsEnumCheck)
2156 if (NeedsEnumCheck &&
2157 getContext().isTypeIgnoredBySanitizer(SanitizerKind::Enum, Ty))
2160 llvm::APInt
Min, End;
2166 NeedsEnumCheck ? SanitizerKind::SO_Enum : SanitizerKind::SO_Bool;
2169 auto CheckHandler = SanitizerHandler::LoadInvalidValue;
2174 Check =
Builder.CreateICmpULE(
Value, llvm::ConstantInt::get(Ctx, End));
2176 llvm::Value *Upper =
2177 Builder.CreateICmpSLE(
Value, llvm::ConstantInt::get(Ctx, End));
2178 llvm::Value *Lower =
2180 Check =
Builder.CreateAnd(Upper, Lower);
2184 EmitCheck(std::make_pair(Check, Kind), CheckHandler, StaticArgs,
Value);
2193 bool isNontemporal) {
2194 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
Addr.getBasePointer()))
2195 if (GV->isThreadLocal())
2201 if (ClangVecTy->isPackedVectorBoolType(
getContext())) {
2203 unsigned ValNumElems =
2206 auto *RawIntV =
Builder.CreateLoad(
Addr, Volatile,
"load_bits");
2207 const auto *RawIntTy = RawIntV->getType();
2208 assert(RawIntTy->isIntegerTy() &&
"compressed iN storage for bitvectors");
2210 auto *PaddedVecTy = llvm::FixedVectorType::get(
2211 Builder.getInt1Ty(), RawIntTy->getPrimitiveSizeInBits());
2212 llvm::Value *
V =
Builder.CreateBitCast(RawIntV, PaddedVecTy);
2225 if (VTy != NewVecTy) {
2227 llvm::Value *
V =
Builder.CreateLoad(Cast, Volatile,
"loadVecN");
2228 unsigned OldNumElements = VTy->getNumElements();
2230 std::iota(Mask.begin(), Mask.end(), 0);
2231 V =
Builder.CreateShuffleVector(
V, Mask,
"extractVec");
2246 llvm::LoadInst *Load =
Builder.CreateLoad(
Addr, Volatile);
2247 if (isNontemporal) {
2248 llvm::MDNode *Node = llvm::MDNode::get(
2249 Load->getContext(), llvm::ConstantAsMetadata::get(
Builder.getInt32(1)));
2250 Load->setMetadata(llvm::LLVMContext::MD_nontemporal, Node);
2253 CGM.DecorateInstructionWithTBAA(Load, TBAAInfo);
2265 Ty = AtomicTy->getValueType();
2273 if (StoreTy->isVectorTy() && StoreTy->getScalarSizeInBits() >
2278 unsigned MemNumElems = StoreTy->getPrimitiveSizeInBits();
2299 Ty = AtomicTy->getValueType();
2305 auto *PaddedVecTy = llvm::FixedVectorType::get(
2306 Builder.getInt1Ty(), RawIntTy->getPrimitiveSizeInBits());
2316 if (HasBoolRep &&
CGM.getCodeGenOpts().isConvertingBoolWithCmp0()) {
2330 bool IsVector =
true) {
2331 auto *ArrayTy = dyn_cast<llvm::ArrayType>(
Addr.getElementType());
2332 if (ArrayTy && IsVector) {
2333 auto ArrayElements = ArrayTy->getNumElements();
2334 auto *ArrayElementTy = ArrayTy->getElementType();
2337 ArrayElementTy = VectorTy->getElementType();
2338 ArrayElements *= VectorTy->getNumElements();
2340 auto *VectorTy = llvm::FixedVectorType::get(ArrayElementTy, ArrayElements);
2342 return Addr.withElementType(VectorTy);
2344 auto *VectorTy = dyn_cast<llvm::VectorType>(
Addr.getElementType());
2345 if (VectorTy && !IsVector) {
2346 auto *ArrayTy = llvm::ArrayType::get(
2347 VectorTy->getElementType(),
2350 return Addr.withElementType(ArrayTy);
2362 "Result must be a Constant Matrix");
2367 if (LTy->getScalarSizeInBits() > Mat->getType()->getScalarSizeInBits())
2368 Mat =
Builder.CreateZExt(Mat, LTy);
2369 Builder.CreateStore(Mat, MatMem);
2387 for (uint32_t &Idx : Indices) {
2389 unsigned Row = Idx / NumCols;
2390 unsigned Col = Idx % NumCols;
2392 Idx = MT->getColumnMajorFlattenedIndex(Row, Col);
2396 if (
Base.isSimple()) {
2400 MatAddr =
CGM.getHLSLRuntime().createBufferMatrixTempAddress(
Base, *
this);
2402 llvm::Constant *CV =
2405 CV, ResultType,
Base.getBaseInfo(),
2408 assert(
Base.isExtVectorElt() &&
"Can only subscript lvalue vec elts here!");
2410 llvm::Constant *BaseElts =
Base.getExtVectorElts();
2413 for (
unsigned Index : Indices)
2414 CElts.push_back(BaseElts->getAggregateElement(Index));
2415 llvm::Constant *CV = llvm::ConstantVector::get(CElts);
2428 value->getType()->isVectorTy());
2430 lvalue.getBaseInfo(), lvalue.getTBAAInfo(), isInit,
2431 lvalue.isNontemporal());
2438 bool isInit,
bool isNontemporal) {
2439 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
Addr.getBasePointer()))
2440 if (GV->isThreadLocal())
2448 if (
auto *VecTy = dyn_cast<llvm::FixedVectorType>(SrcTy)) {
2450 CGM.getABIInfo().getOptimalVectorMemoryType(VecTy,
getLangOpts());
2451 if (!ClangVecTy->isPackedVectorBoolType(
getContext()) &&
2452 VecTy != NewVecTy) {
2454 VecTy->getNumElements());
2455 std::iota(Mask.begin(), Mask.begin() + VecTy->getNumElements(), 0);
2459 Mask,
"extractVec");
2462 if (
Addr.getElementType() != SrcTy)
2463 Addr =
Addr.withElementType(SrcTy);
2480 if (isNontemporal) {
2481 llvm::MDNode *Node =
2482 llvm::MDNode::get(Store->getContext(),
2483 llvm::ConstantAsMetadata::get(
Builder.getInt32(1)));
2484 Store->setMetadata(llvm::LLVMContext::MD_nontemporal, Node);
2487 CGM.DecorateInstructionWithTBAA(Store, TBAAInfo);
2506 assert(LV.getType()->isConstantMatrixType());
2516 LV.setAddress(
Addr);
2532 llvm_unreachable(
"bad evaluation kind");
2598 EltTy = MatTy->getElementType();
2599 if (
CGM.getCodeGenOpts().isOptimizedBuild()) {
2600 llvm::MatrixBuilder MB(
Builder);
2601 MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened());
2604 llvm::LoadInst *Load =
2606 llvm::Value *Elt =
Builder.CreateExtractElement(Load, Idx,
"matrixext");
2615 unsigned NumLanes = NumCols;
2619 llvm::Constant *ColConstsIndices =
nullptr;
2620 llvm::MatrixBuilder MB(
Builder);
2624 NumLanes = llvm::cast<llvm::FixedVectorType>(ColConstsIndices->getType())
2628 llvm::Type *RowTy = llvm::FixedVectorType::get(ElemTy, NumLanes);
2629 llvm::Value *
Result = llvm::PoisonValue::get(RowTy);
2631 for (
unsigned Col = 0; Col < NumLanes; ++Col) {
2632 llvm::Value *ColIdx;
2633 if (ColConstsIndices)
2634 ColIdx = ColConstsIndices->getAggregateElement(Col);
2636 ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
2638 llvm::Value *EltIndex =
2639 MB.CreateIndex(Row, ColIdx, NumRows, NumCols, IsMatrixRowMajor);
2640 llvm::Value *Elt =
Builder.CreateExtractElement(MatrixVec, EltIndex);
2641 llvm::Value *Lane = llvm::ConstantInt::get(
Builder.getInt32Ty(), Col);
2648 assert(LV.
isBitField() &&
"Unknown LValue type!");
2667 const unsigned StorageSize =
2670 assert(
static_cast<unsigned>(Offset + Info.
Size) <= StorageSize);
2671 unsigned HighBits = StorageSize - Offset - Info.
Size;
2673 Val =
Builder.CreateShl(Val, HighBits,
"bf.shl");
2674 if (Offset + HighBits)
2675 Val =
Builder.CreateAShr(Val, Offset + HighBits,
"bf.ashr");
2678 Val =
Builder.CreateLShr(Val, Offset,
"bf.lshr");
2679 if (
static_cast<unsigned>(Offset) + Info.
Size < StorageSize)
2681 Val, llvm::APInt::getLowBitsSet(StorageSize, Info.
Size),
"bf.clear");
2697 llvm::Type *DstTy = llvm::FixedVectorType::get(Vec->getType(), 1);
2698 llvm::Value *
Zero = llvm::Constant::getNullValue(
CGM.Int64Ty);
2699 Vec =
Builder.CreateInsertElement(DstTy, Vec,
Zero,
"cast.splat");
2709 llvm::Value *Elt = llvm::ConstantInt::get(
SizeTy, InIdx);
2711 llvm::Value *Element =
Builder.CreateExtractElement(Vec, Elt);
2714 if (Element->getType()->getPrimitiveSizeInBits() >
2715 LVTy->getPrimitiveSizeInBits()) {
2717 CGM.getCodeGenOpts().isConvertingBoolWithCmp0())
2718 Element =
Builder.CreateICmpNE(
2719 Element, llvm::Constant::getNullValue(Element->getType()));
2721 Element =
Builder.CreateTrunc(Element, LVTy);
2731 for (
unsigned i = 0; i != NumResultElts; ++i)
2734 Vec =
Builder.CreateShuffleVector(Vec, Mask);
2737 if (
CGM.getCodeGenOpts().isConvertingBoolWithCmp0())
2738 Vec =
Builder.CreateICmpNE(Vec,
2739 llvm::Constant::getNullValue(Vec->getType()));
2751 llvm::Type *VectorElementTy =
CGM.getTypes().ConvertType(EQT);
2759 Builder.CreateConstInBoundsGEP(CastToPointerElement, ix,
2762 return VectorBasePtrPlusIx;
2768 "Bad type for register variable");
2773 llvm::Type *OrigTy =
CGM.getTypes().ConvertType(LV.
getType());
2774 llvm::Type *Ty = OrigTy;
2775 if (OrigTy->isPointerTy())
2776 Ty =
CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
2777 llvm::Type *Types[] = { Ty };
2779 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::read_register, Types);
2781 F, llvm::MetadataAsValue::get(Ty->getContext(), RegName));
2782 if (OrigTy->isPointerTy())
2800 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2802 CGM.getDataLayout().getPrefTypeAlign(ElemTy));
2804 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2805 "vector element type must be at least byte-sized");
2808 if (Val->getType()->getPrimitiveSizeInBits() <
2809 ElemTy->getScalarSizeInBits())
2810 Val =
Builder.CreateZExt(Val, ElemTy->getScalarType());
2813 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2815 Builder.CreateGEP(DstAddr, {
Zero, Idx}, DestAddrTy, ElemAlign);
2823 llvm::Type *VecTy = Vec->getType();
2826 if (VecTy->isVectorTy() && SrcVal->getType()->getPrimitiveSizeInBits() <
2827 VecTy->getScalarSizeInBits())
2828 SrcVal =
Builder.CreateZExt(SrcVal, VecTy->getScalarType());
2830 auto *IRStoreTy = dyn_cast<llvm::IntegerType>(Vec->getType());
2832 auto *IRVecTy = llvm::FixedVectorType::get(
2833 Builder.getInt1Ty(), IRStoreTy->getPrimitiveSizeInBits());
2834 Vec =
Builder.CreateBitCast(Vec, IRVecTy);
2841 if (
auto *EltTy = dyn_cast<llvm::FixedVectorType>(SrcVal->getType());
2842 EltTy && EltTy->getNumElements() == 1)
2843 SrcVal =
Builder.CreateBitCast(SrcVal, EltTy->getElementType());
2849 Vec =
Builder.CreateBitCast(Vec, IRStoreTy);
2873 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2875 CGM.getDataLayout().getPrefTypeAlign(ElemTy));
2877 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2878 "matrix element type must be at least byte-sized");
2881 if (Val->getType()->getPrimitiveSizeInBits() <
2882 ElemTy->getScalarSizeInBits())
2883 Val =
Builder.CreateZExt(Val, ElemTy->getScalarType());
2886 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2888 Builder.CreateGEP(DstAddr, {
Zero, Idx}, DestAddrTy, ElemAlign);
2894 if (
CGM.getCodeGenOpts().isOptimizedBuild()) {
2896 llvm::MatrixBuilder MB(
Builder);
2897 MB.CreateIndexAssumption(Idx, MatTy->getNumElementsFlattened());
2902 Builder.CreateInsertElement(Load, InsertVal, Idx,
"matins");
2913 "Store through matrix row LValues is only implemented for HLSL!");
2919 unsigned NumLanes = NumCols;
2923 llvm::Type *ElemTy = DestAddrTy->getScalarType();
2927 assert(ElemTy->getScalarSizeInBits() >= 8 &&
2928 "matrix element type must be at least byte-sized");
2931 if (RowVal->getType()->getScalarType()->getPrimitiveSizeInBits() <
2932 ElemTy->getScalarSizeInBits()) {
2934 llvm::Type *StorageElmTy = llvm::FixedVectorType::get(
2935 ElemTy->getScalarType(), RowValVecTy->getNumElements());
2936 RowVal =
Builder.CreateZExt(RowVal, StorageElmTy);
2939 llvm::MatrixBuilder MB(
Builder);
2941 llvm::Constant *ColConstsIndices =
nullptr;
2945 llvm::cast<llvm::FixedVectorType>(ColConstsIndices->getType())
2950 for (
unsigned Col = 0; Col < NumLanes; ++Col) {
2951 llvm::Value *ColIdx;
2952 if (ColConstsIndices)
2953 ColIdx = ColConstsIndices->getAggregateElement(Col);
2955 ColIdx = llvm::ConstantInt::get(Row->getType(), Col);
2957 llvm::Value *EltIndex =
2958 MB.CreateIndex(Row, ColIdx, NumRows, NumCols, IsMatrixRowMajor);
2959 llvm::Value *Lane = llvm::ConstantInt::get(
Builder.getInt32Ty(), Col);
2960 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
2961 llvm::Value *NewElt =
Builder.CreateExtractElement(RowVal, Lane);
2963 Builder.CreateGEP(DstAddr, {
Zero, EltIndex}, DestAddrTy, ElemAlign);
2970 assert(Dst.
isBitField() &&
"Unknown LValue type");
2985 llvm_unreachable(
"present but none");
3020 CGM.getObjCRuntime().EmitObjCWeakAssign(*
this, src, LvalueDst);
3033 RHS =
Builder.CreatePtrToInt(RHS, ResultType,
"sub.ptr.rhs.cast");
3035 ResultType,
"sub.ptr.lhs.cast");
3036 llvm::Value *BytesBetween =
Builder.CreateSub(LHS, RHS,
"ivar.offset");
3037 CGM.getObjCRuntime().EmitObjCIvarAssign(*
this, src, dst, BytesBetween);
3039 CGM.getObjCRuntime().EmitObjCGlobalAssign(*
this, src, LvalueDst,
3043 CGM.getObjCRuntime().EmitObjCStrongCastAssign(*
this, src, LvalueDst);
3047 assert(Src.
isScalar() &&
"Can't emit an agg store with this method");
3061 SrcVal =
Builder.CreateIntCast(SrcVal, Ptr.getElementType(),
3063 llvm::Value *MaskedVal = SrcVal;
3065 const bool UseVolatile =
3068 const unsigned StorageSize =
3073 if (StorageSize != Info.
Size) {
3074 assert(StorageSize > Info.
Size &&
"Invalid bitfield size.");
3081 SrcVal, llvm::APInt::getLowBitsSet(StorageSize, Info.
Size),
3085 SrcVal =
Builder.CreateShl(SrcVal, Offset,
"bf.shl");
3089 Val, ~llvm::APInt::getBitsSet(StorageSize, Offset, Offset + Info.
Size),
3093 SrcVal =
Builder.CreateOr(Val, SrcVal,
"bf.set");
3095 assert(Offset == 0);
3102 CGM.getCodeGenOpts().ForceAAPCSBitfieldLoad)
3103 Builder.CreateLoad(Ptr,
true,
"bf.load");
3112 llvm::Value *ResultVal = MaskedVal;
3116 assert(Info.
Size <= StorageSize);
3117 unsigned HighBits = StorageSize - Info.
Size;
3119 ResultVal =
Builder.CreateShl(ResultVal, HighBits,
"bf.result.shl");
3120 ResultVal =
Builder.CreateAShr(ResultVal, HighBits,
"bf.result.ashr");
3136 SrcVal->getType()->getScalarSizeInBits())
3145 if (!DestAddrTy->isVectorTy()) {
3147 "this should only occur for non-vector l-values");
3160 CGM.getDataLayout().getPrefTypeAlign(DestAddrTy->getScalarType()));
3161 llvm::Value *
Zero = llvm::ConstantInt::get(
Int32Ty, 0);
3163 for (
unsigned I = 0; I != NumSrcElts; ++I) {
3164 llvm::Value *Val = VTy ?
Builder.CreateExtractElement(
3165 SrcVal, llvm::ConstantInt::get(
Int32Ty, I))
3172 DstElemAddr =
Builder.CreateGEP(
3173 DstAddr, {
Zero, llvm::ConstantInt::get(
Int32Ty, FieldNo)},
3174 DestAddrTy, ElemAlign);
3183 llvm::Type *VecTy = Vec->getType();
3186 unsigned NumSrcElts = VTy->getNumElements();
3188 if (NumDstElts == NumSrcElts) {
3193 for (
unsigned i = 0; i != NumSrcElts; ++i)
3196 Vec =
Builder.CreateShuffleVector(SrcVal, Mask);
3197 }
else if (NumDstElts > NumSrcElts) {
3203 for (
unsigned i = 0; i != NumSrcElts; ++i)
3204 ExtMask.push_back(i);
3205 ExtMask.resize(NumDstElts, -1);
3206 llvm::Value *ExtSrcVal =
Builder.CreateShuffleVector(SrcVal, ExtMask);
3209 for (
unsigned i = 0; i != NumDstElts; ++i)
3219 for (
unsigned i = 0; i != NumSrcElts; ++i)
3221 Vec =
Builder.CreateShuffleVector(Vec, ExtSrcVal, Mask);
3224 llvm_unreachable(
"unexpected shorten vector length");
3230 llvm::Value *Elt = llvm::ConstantInt::get(
SizeTy, InIdx);
3232 Vec =
Builder.CreateInsertElement(Vec, SrcVal, Elt);
3242 "Bad type for register variable");
3245 assert(RegName &&
"Register LValue is not metadata");
3248 llvm::Type *OrigTy =
CGM.getTypes().ConvertType(Dst.
getType());
3249 llvm::Type *Ty = OrigTy;
3250 if (OrigTy->isPointerTy())
3251 Ty =
CGM.getTypes().getDataLayout().getIntPtrType(OrigTy);
3252 llvm::Type *Types[] = { Ty };
3254 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::write_register, Types);
3256 if (OrigTy->isPointerTy())
3259 F, {llvm::MetadataAsValue::get(Ty->getContext(), RegName),
Value});
3267 bool IsMemberAccess=
false) {
3279 LV.setObjCIvar(
false);
3283 LV.setObjCIvar(
true);
3285 LV.setBaseIvarExp(Exp->getBase());
3290 if (
const auto *Exp = dyn_cast<DeclRefExpr>(E)) {
3291 if (
const auto *VD = dyn_cast<VarDecl>(Exp->getDecl())) {
3292 if (VD->hasGlobalStorage()) {
3293 LV.setGlobalObjCRef(
true);
3301 if (
const auto *Exp = dyn_cast<UnaryOperator>(E)) {
3306 if (
const auto *Exp = dyn_cast<ParenExpr>(E)) {
3308 if (LV.isObjCIvar()) {
3315 LV.setObjCIvar(
false);
3320 if (
const auto *Exp = dyn_cast<GenericSelectionExpr>(E)) {
3325 if (
const auto *Exp = dyn_cast<ImplicitCastExpr>(E)) {
3330 if (
const auto *Exp = dyn_cast<CStyleCastExpr>(E)) {
3335 if (
const auto *Exp = dyn_cast<ObjCBridgedCastExpr>(E)) {
3340 if (
const auto *Exp = dyn_cast<ArraySubscriptExpr>(E)) {
3342 if (LV.isObjCIvar() && !LV.isObjCArray())
3345 LV.setObjCIvar(
false);
3346 else if (LV.isGlobalObjCRef() && !LV.isObjCArray())
3349 LV.setGlobalObjCRef(
false);
3353 if (
const auto *Exp = dyn_cast<MemberExpr>(E)) {
3367 CGF, VD,
Addr, Loc);
3372 Addr =
Addr.withElementType(RealVarTy);
3378 std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3379 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3384 if (!Res || *Res == OMPDeclareTargetDeclAttr::MT_Local ||
3385 ((*Res == OMPDeclareTargetDeclAttr::MT_To ||
3386 *Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
3389 assert(((*Res == OMPDeclareTargetDeclAttr::MT_Link) ||
3390 ((*Res == OMPDeclareTargetDeclAttr::MT_To ||
3391 *Res == OMPDeclareTargetDeclAttr::MT_Enter) &&
3393 "Expected link clause OR to clause with unified memory enabled.");
3403 llvm::LoadInst *Load =
3408 PTy, PointeeBaseInfo, PointeeTBAAInfo,
true);
3411 llvm::MDBuilder MDB(Ctx);
3413 if (
CGM.getTypes().getTargetAddressSpace(PTy) == 0 &&
3414 !
CGM.getCodeGenOpts().NullPointerIsValid)
3415 Load->setMetadata(llvm::LLVMContext::MD_nonnull,
3416 llvm::MDNode::get(Ctx, {}));
3422 llvm::LLVMContext::MD_align,
3423 llvm::MDNode::get(Ctx, MDB.createConstant(llvm::ConstantInt::get(
3424 Builder.getInt64Ty(), AlignVal))));
3429 true, PointeeBaseInfo,
3439 PointeeBaseInfo, PointeeTBAAInfo);
3449 BaseInfo, TBAAInfo);
3479 std::optional<LValue> LV =
3488 V = CGF.
Builder.CreateThreadLocalAddress(
V);
3496 VD->
hasAttr<OMPThreadPrivateDeclAttr>()) {
3511 if (FD->
hasAttr<WeakRefAttr>()) {
3526 if (
auto *GV = dyn_cast<llvm::GlobalValue>(
V))
3527 V = llvm::NoCFIValue::get(GV);
3534 llvm::Value *ThisValue) {
3547 AsmLabelAttr *
Asm = VD->
getAttr<AsmLabelAttr>();
3548 assert(
Asm->getLabel().size() < 64-Name.size() &&
3549 "Register name too big");
3550 Name.append(
Asm->getLabel());
3551 llvm::NamedMDNode *M =
3552 CGM.
getModule().getOrInsertNamedMetadata(Name);
3553 if (M->getNumOperands() == 0) {
3556 llvm::Metadata *Ops[] = {Str};
3563 llvm::MetadataAsValue::get(CGM.
getLLVMContext(), M->getOperand(0));
3606 case llvm::GlobalValue::ExternalLinkage:
3607 case llvm::GlobalValue::LinkOnceODRLinkage:
3608 case llvm::GlobalValue::WeakODRLinkage:
3609 case llvm::GlobalValue::InternalLinkage:
3610 case llvm::GlobalValue::PrivateLinkage:
3622 "should not emit an unevaluated operand");
3624 if (
const auto *VD = dyn_cast<VarDecl>(ND)) {
3627 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())
3635 (VD->getType()->isReferenceType() ||
3637 VD->getAnyInitializer(VD);
3639 E->
getLocation(), *VD->evaluateValue(), VD->getType());
3640 assert(Val &&
"failed to emit constant expression");
3643 if (!VD->getType()->isReferenceType()) {
3645 Addr =
CGM.createUnnamedGlobalFrom(*VD, Val,
3648 auto *PTy = llvm::PointerType::get(
3667 VD = VD->getCanonicalDecl();
3671 auto I = LocalDeclMap.find(VD);
3672 if (I != LocalDeclMap.end()) {
3674 if (VD->getType()->isReferenceType())
3682 CGM.getOpenMPRuntime().isNontemporalDecl(VD))
3699 CGM.getOpenMPRuntime().isNontemporalDecl(VD))
3715 "Should not use decl without marking it used!");
3717 if (ND->
hasAttr<WeakRefAttr>()) {
3723 if (
const auto *VD = dyn_cast<VarDecl>(ND)) {
3725 if (VD->hasLinkage() || VD->isStaticDataMember())
3731 auto iter = LocalDeclMap.find(VD);
3732 if (iter != LocalDeclMap.end()) {
3733 addr = iter->second;
3737 }
else if (VD->isStaticLocal()) {
3738 llvm::Constant *var =
CGM.getOrCreateStaticVarDecl(
3739 *VD,
CGM.getLLVMLinkageVarDefinition(VD));
3745 llvm_unreachable(
"DeclRefExpr for Decl not entered in LocalDeclMap?");
3756 VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
3763 bool isBlockByref = VD->isEscapingByref();
3769 LValue LV = VD->getType()->isReferenceType() ?
3773 bool isLocalStorage = VD->hasLocalStorage();
3775 bool NonGCable = isLocalStorage &&
3776 !VD->getType()->isReferenceType() &&
3783 bool isImpreciseLifetime =
3784 (isLocalStorage && !VD->hasAttr<ObjCPreciseLifetimeAttr>());
3785 if (isImpreciseLifetime)
3791 if (
const auto *FD = dyn_cast<FunctionDecl>(ND))
3797 if (
const auto *BD = dyn_cast<BindingDecl>(ND)) {
3814 if (
const auto *GD = dyn_cast<MSGuidDecl>(ND))
3818 if (
const auto *TPO = dyn_cast<TemplateParamObjectDecl>(ND)) {
3822 if (AS !=
T.getAddressSpace()) {
3825 llvm::PointerType::get(
CGM.getLLVMContext(), TargetAS);
3826 llvm::Constant *ASC =
CGM.performAddrSpaceCast(ATPO.
getPointer(), PtrTy);
3833 llvm_unreachable(
"Unhandled DeclRefExpr");
3843 default: llvm_unreachable(
"Unknown unary operator lvalue!");
3846 assert(!
T.isNull() &&
"CodeGenFunction::EmitUnaryOpLValue: Illegal type");
3868 assert(LV.
isSimple() &&
"real/imag on non-ordinary l-value");
3885 CGM.getTBAAInfoForSubobject(LV,
T));
3892 bool isInc = E->
getOpcode() == UO_PreInc;
3915 assert(SL !=
nullptr &&
"No StringLiteral name in PredefinedExpr");
3916 StringRef FnName =
CurFn->getName();
3917 FnName.consume_front(
"\01");
3918 StringRef NameItems[] = {
3920 std::string GVName = llvm::join(NameItems, NameItems + 2,
".");
3921 if (
auto *BD = dyn_cast_or_null<BlockDecl>(
CurCodeDecl)) {
3922 std::string Name = std::string(SL->getString());
3923 if (!Name.empty()) {
3924 unsigned Discriminator =
3925 CGM.getCXXABI().getMangleContext().getBlockId(BD,
true);
3927 Name +=
"_" + Twine(Discriminator + 1).str();
3928 auto C =
CGM.GetAddrOfConstantCString(Name, GVName);
3931 auto C =
CGM.GetAddrOfConstantCString(std::string(FnName), GVName);
3935 auto C =
CGM.GetAddrOfConstantStringFromLiteral(SL, GVName);
3952 if (llvm::Constant *
C =
CGM.getTypeDescriptorFromMap(
T))
3957 bool IsBitInt =
false;
3959 if (
T->isIntegerType()) {
3962 (
T->isSignedIntegerType() ? 1 : 0);
3966 if (
T->isSignedIntegerType() &&
T->getAs<
BitIntType>()) {
3969 " non positive amount of bits in __BitInt type");
3971 " too many bits in __BitInt type");
3978 }
else if (
T->isFloatingType()) {
3987 (
intptr_t)
T.getAsOpaquePtr(), StringRef(),
3988 StringRef(), {}, Buffer, {});
3993 char S[6] = {
'\0',
'\0',
'\0',
'\0',
'\0',
'\0'};
3996 llvm::support::endian::write32(S + 1, Bits,
3998 ? llvm::endianness::big
3999 : llvm::endianness::little);
4000 StringRef Str = StringRef(S,
sizeof(S) /
sizeof(
decltype(S[0])));
4004 llvm::Constant *Components[] = {
4008 llvm::Constant *Descriptor = llvm::ConstantStruct::getAnon(Components);
4010 auto *GV =
new llvm::GlobalVariable(
4011 CGM.getModule(), Descriptor->getType(),
4012 true, llvm::GlobalVariable::PrivateLinkage, Descriptor);
4013 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4014 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(GV);
4017 CGM.setTypeDescriptorInMap(
T, GV);
4025 if (
V->getType() == TargetTy)
4030 if (
V->getType()->isFloatingPointTy()) {
4031 unsigned Bits =
V->getType()->getPrimitiveSizeInBits().getFixedValue();
4032 if (Bits <= TargetTy->getIntegerBitWidth())
4038 if (
V->getType()->isIntegerTy() &&
4039 V->getType()->getIntegerBitWidth() <= TargetTy->getIntegerBitWidth())
4040 return Builder.CreateZExt(
V, TargetTy);
4043 if (!
V->getType()->isPointerTy()) {
4046 V = Ptr.getPointer();
4048 return Builder.CreatePtrToInt(
V, TargetTy);
4061 llvm::Constant *Filename;
4068 int PathComponentsToStrip =
4069 CGM.getCodeGenOpts().EmitCheckPathComponentsToStrip;
4070 if (PathComponentsToStrip < 0) {
4071 assert(PathComponentsToStrip !=
INT_MIN);
4072 int PathComponentsToKeep = -PathComponentsToStrip;
4073 auto I = llvm::sys::path::rbegin(FilenameString);
4074 auto E = llvm::sys::path::rend(FilenameString);
4075 while (I != E && --PathComponentsToKeep)
4078 FilenameString = FilenameString.substr(I - E);
4079 }
else if (PathComponentsToStrip > 0) {
4080 auto I = llvm::sys::path::begin(FilenameString);
4081 auto E = llvm::sys::path::end(FilenameString);
4082 while (I != E && PathComponentsToStrip--)
4087 FilenameString.substr(I - llvm::sys::path::begin(FilenameString));
4089 FilenameString = llvm::sys::path::filename(FilenameString);
4093 CGM.GetAddrOfConstantCString(std::string(FilenameString),
".src");
4094 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(
4096 FilenameGV.getPointer()->stripPointerCasts()));
4097 Filename = FilenameGV.getPointer();
4101 Filename = llvm::Constant::getNullValue(
Int8PtrTy);
4108 return llvm::ConstantStruct::getAnon(
Data);
4113enum class CheckRecoverableKind {
4124static CheckRecoverableKind
4126 if (Ordinal == SanitizerKind::SO_Vptr)
4127 return CheckRecoverableKind::AlwaysRecoverable;
4128 else if (Ordinal == SanitizerKind::SO_Return ||
4129 Ordinal == SanitizerKind::SO_Unreachable)
4130 return CheckRecoverableKind::Unrecoverable;
4132 return CheckRecoverableKind::Recoverable;
4136struct SanitizerHandlerInfo {
4137 char const *
const Name;
4143#define SANITIZER_CHECK(Enum, Name, Version, Msg) {#Name, Version},
4145#undef SANITIZER_CHECK
4149 llvm::FunctionType *FnType,
4152 CheckRecoverableKind RecoverKind,
bool IsFatal,
4153 llvm::BasicBlock *ContBB,
bool NoMerge) {
4154 assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
4155 std::optional<ApplyDebugLocation> DL;
4156 if (!CGF.
Builder.getCurrentDebugLocation()) {
4160 bool NeedsAbortSuffix =
4161 IsFatal && RecoverKind != CheckRecoverableKind::Unrecoverable;
4163 bool HandlerPreserveAllRegs =
4166 const StringRef CheckName = CheckInfo.Name;
4167 std::string FnName =
"__ubsan_handle_" + CheckName.str();
4168 if (CheckInfo.Version && !MinimalRuntime)
4169 FnName +=
"_v" + llvm::utostr(CheckInfo.Version);
4171 FnName +=
"_minimal";
4172 if (NeedsAbortSuffix)
4174 if (HandlerPreserveAllRegs && !NeedsAbortSuffix)
4175 FnName +=
"_preserve";
4177 !IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable;
4181 B.addAttribute(llvm::Attribute::NoReturn)
4182 .addAttribute(llvm::Attribute::NoUnwind);
4184 B.addUWTableAttr(llvm::UWTableKind::Default);
4189 llvm::AttributeList::FunctionIndex, B),
4195 HandlerCall->addFnAttr(llvm::Attribute::NoMerge);
4196 if (HandlerPreserveAllRegs && !NeedsAbortSuffix) {
4198 HandlerCall->setCallingConv(llvm::CallingConv::PreserveAll);
4201 HandlerCall->setDoesNotReturn();
4202 CGF.
Builder.CreateUnreachable();
4209 ArrayRef<std::pair<llvm::Value *, SanitizerKind::SanitizerOrdinal>> Checked,
4213 assert(Checked.size() > 0);
4214 assert(CheckHandler >= 0 &&
4218 llvm::Value *FatalCond =
nullptr;
4219 llvm::Value *RecoverableCond =
nullptr;
4220 llvm::Value *TrapCond =
nullptr;
4221 bool NoMerge =
false;
4228 for (
auto &[Check, Ord] : Checked) {
4229 llvm::Value *GuardedCheck = Check;
4231 (
CGM.getCodeGenOpts().SanitizeSkipHotCutoffs[Ord] > 0)) {
4233 CGM.getIntrinsic(llvm::Intrinsic::allow_ubsan_check),
4234 llvm::ConstantInt::get(
CGM.Int8Ty, Ord));
4239 llvm::Value *&Cond =
CGM.getCodeGenOpts().SanitizeTrap.has(Ord) ? TrapCond
4240 :
CGM.getCodeGenOpts().SanitizeRecover.has(Ord)
4243 Cond = Cond ?
Builder.CreateAnd(Cond, GuardedCheck) : GuardedCheck;
4245 if (!
CGM.getCodeGenOpts().SanitizeMergeHandlers.has(Ord))
4251 if (!FatalCond && !RecoverableCond)
4254 llvm::Value *JointCond;
4255 if (FatalCond && RecoverableCond)
4256 JointCond =
Builder.CreateAnd(FatalCond, RecoverableCond);
4258 JointCond = FatalCond ? FatalCond : RecoverableCond;
4262 assert(
SanOpts.has(Checked[0].second));
4264 for (
int i = 1, n = Checked.size(); i < n; ++i) {
4266 "All recoverable kinds in a single check must be same!");
4267 assert(
SanOpts.has(Checked[i].second));
4273 llvm::Instruction *Branch =
Builder.CreateCondBr(JointCond, Cont, Handlers);
4276 llvm::MDNode *Node = MDHelper.createLikelyBranchWeights();
4277 Branch->setMetadata(llvm::LLVMContext::MD_prof, Node);
4281 if (
CGM.getCodeGenOpts().SanitizeMinimalRuntime) {
4292 Args.reserve(DynamicArgs.size() + 1);
4293 ArgTypes.reserve(DynamicArgs.size() + 1);
4296 if (!StaticArgs.empty()) {
4297 llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
4298 auto *InfoPtr =
new llvm::GlobalVariable(
4299 CGM.getModule(), Info->getType(),
4302 false, llvm::GlobalVariable::PrivateLinkage, Info,
"",
4303 nullptr, llvm::GlobalVariable::NotThreadLocal,
4304 CGM.getDataLayout().getDefaultGlobalsAddressSpace());
4305 InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4306 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
4307 Args.push_back(
Builder.CreateAddrSpaceCast(InfoPtr,
CGM.VoidPtrTy));
4308 ArgTypes.push_back(
CGM.VoidPtrTy);
4311 for (llvm::Value *DynamicArg : DynamicArgs) {
4316 llvm::FunctionType *FnType =
4317 llvm::FunctionType::get(
CGM.VoidTy, ArgTypes,
false);
4319 if (!FatalCond || !RecoverableCond) {
4323 (FatalCond !=
nullptr), Cont, NoMerge);
4327 llvm::BasicBlock *NonFatalHandlerBB =
4330 Builder.CreateCondBr(FatalCond, NonFatalHandlerBB, FatalHandlerBB);
4333 NonFatalHandlerBB, NoMerge);
4344 llvm::ConstantInt *TypeId, llvm::Value *Ptr,
4349 llvm::CondBrInst *BI =
Builder.CreateCondBr(Cond, Cont, CheckBB);
4352 llvm::MDNode *Node = MDHelper.createLikelyBranchWeights();
4353 BI->setMetadata(llvm::LLVMContext::MD_prof, Node);
4357 bool WithDiag = !
CGM.getCodeGenOpts().SanitizeTrap.has(Ordinal);
4359 llvm::CallInst *CheckCall;
4360 llvm::FunctionCallee SlowPathFn;
4362 llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
4364 new llvm::GlobalVariable(
CGM.getModule(), Info->getType(),
false,
4365 llvm::GlobalVariable::PrivateLinkage, Info);
4366 InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
4367 CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
4369 SlowPathFn =
CGM.getModule().getOrInsertFunction(
4370 "__cfi_slowpath_diag",
4373 CheckCall =
Builder.CreateCall(SlowPathFn, {TypeId, Ptr, InfoPtr});
4375 SlowPathFn =
CGM.getModule().getOrInsertFunction(
4378 CheckCall =
Builder.CreateCall(SlowPathFn, {TypeId, Ptr});
4383 CheckCall->setDoesNotThrow();
4391 llvm::Module *M = &
CGM.getModule();
4393 QualType QInt64Ty =
C.getIntTypeForBitwidth(64,
false);
4395 auto *ArgCallsiteTypeId =
4399 auto *ArgCFICheckFailData =
4403 CGM.getTypes().arrangeBuiltinFunctionDeclaration(
C.VoidTy,
FnArgs);
4405 llvm::Function *F = llvm::Function::Create(
4407 llvm::GlobalValue::WeakAnyLinkage,
"__cfi_check", M);
4409 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
4410 F->setAlignment(llvm::Align(4096));
4413 llvm::LLVMContext &Ctx = M->getContext();
4414 llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx,
"entry", F);
4417 llvm::CallInst::Create(M->getFunction(
"__cfi_check_fail"), Args,
"", BB);
4418 llvm::ReturnInst::Create(Ctx,
nullptr, BB);
4429 auto CheckHandler = SanitizerHandler::CFICheckFail;
4436 {SanitizerKind::SO_CFIVCall, SanitizerKind::SO_CFINVCall,
4437 SanitizerKind::SO_CFIDerivedCast, SanitizerKind::SO_CFIUnrelatedCast,
4438 SanitizerKind::SO_CFIICall},
4449 llvm::Function *F = llvm::Function::Create(
4451 llvm::GlobalValue::WeakODRLinkage,
"__cfi_check_fail", &
CGM.getModule());
4454 CGM.SetLLVMFunctionAttributesForDefinition(
nullptr, F);
4455 F->setVisibility(llvm::GlobalValue::HiddenVisibility);
4469 CGM.getContext().VoidPtrTy, ArgData->getLocation());
4472 CGM.getContext().VoidPtrTy, ArgAddr->getLocation());
4475 llvm::Value *DataIsNotNullPtr =
4480 EmitTrapCheck(DataIsNotNullPtr, SanitizerHandler::CFICheckFail,
4483 llvm::StructType *SourceLocationTy =
4485 llvm::StructType *CfiCheckFailDataTy =
4488 llvm::Value *
V =
Builder.CreateConstGEP2_32(
4492 llvm::Value *CheckKind =
Builder.CreateLoad(CheckKindAddr);
4494 llvm::Value *AllVtables = llvm::MetadataAsValue::get(
4495 CGM.getLLVMContext(),
4496 llvm::MDString::get(
CGM.getLLVMContext(),
"all-vtables"));
4497 llvm::Value *ValidVtable =
Builder.CreateZExt(
4498 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::type_test),
4499 {Addr, AllVtables}),
4502 const std::pair<int, SanitizerKind::SanitizerOrdinal> CheckKinds[] = {
4509 for (
auto CheckKindOrdinalPair : CheckKinds) {
4510 int Kind = CheckKindOrdinalPair.first;
4517 Builder.CreateICmpNE(CheckKind, llvm::ConstantInt::get(
Int8Ty, Kind));
4518 if (
CGM.getLangOpts().Sanitize.has(Ordinal))
4519 EmitCheck(std::make_pair(Cond, Ordinal), SanitizerHandler::CFICheckFail,
4532 CGM.addUsedGlobal(F);
4536 if (
SanOpts.has(SanitizerKind::Unreachable)) {
4537 auto CheckOrdinal = SanitizerKind::SO_Unreachable;
4538 auto CheckHandler = SanitizerHandler::BuiltinUnreachable;
4554 if ((
int)TrapBBs.size() <= CheckHandlerID)
4555 TrapBBs.resize(CheckHandlerID + 1);
4557 llvm::BasicBlock *&TrapBB = TrapBBs[CheckHandlerID];
4559 llvm::DILocation *TrapLocation =
Builder.getCurrentDebugLocation();
4560 llvm::StringRef TrapMessage;
4561 llvm::StringRef TrapCategory;
4562 auto DebugTrapReasonKind =
CGM.getCodeGenOpts().getSanitizeDebugTrapReasons();
4564 DebugTrapReasonKind ==
4570 TrapCategory =
"Undefined Behavior Sanitizer";
4574 DebugTrapReasonKind !=
4578 TrapLocation, TrapCategory, TrapMessage);
4581 NoMerge = NoMerge || !
CGM.getCodeGenOpts().isOptimizedBuild() ||
4585 if (TrapBB && !NoMerge) {
4586 auto Call = TrapBB->begin();
4589 Call->applyMergedLocation(
Call->getDebugLoc(), TrapLocation);
4591 Builder.CreateCondBr(Checked, Cont, TrapBB,
4592 MDHelper.createLikelyBranchWeights());
4595 Builder.CreateCondBr(Checked, Cont, TrapBB,
4596 MDHelper.createLikelyBranchWeights());
4601 llvm::CallInst *TrapCall;
4602 if (
CGM.getCodeGenOpts().SanitizeTrapLoop)
4604 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::looptrap));
4606 TrapCall =
Builder.CreateCall(
4607 CGM.getIntrinsic(llvm::Intrinsic::ubsantrap),
4608 llvm::ConstantInt::get(
CGM.Int8Ty, CheckHandlerID));
4610 if (!
CGM.getCodeGenOpts().TrapFuncName.empty()) {
4611 auto A = llvm::Attribute::get(
getLLVMContext(),
"trap-func-name",
4612 CGM.getCodeGenOpts().TrapFuncName);
4613 TrapCall->addFnAttr(A);
4616 TrapCall->addFnAttr(llvm::Attribute::NoMerge);
4617 TrapCall->setDoesNotReturn();
4618 TrapCall->setDoesNotThrow();
4627 llvm::Function *TrapIntrinsic =
CGM.getIntrinsic(IntrID);
4628 llvm::CallInst *TrapCall =
Builder.CreateCall(TrapIntrinsic);
4630 if (!
CGM.getCodeGenOpts().TrapFuncName.empty()) {
4631 auto A = llvm::Attribute::get(
getLLVMContext(),
"trap-func-name",
4632 CGM.getCodeGenOpts().TrapFuncName);
4633 TrapCall->addFnAttr(A);
4637 TrapCall->addFnAttr(llvm::Attribute::NoMerge);
4638 if (TrapIntrinsic->doesNotThrow())
4639 TrapCall->setDoesNotThrow();
4640 if (TrapIntrinsic->doesNotReturn()) {
4641 TrapCall->setDoesNotReturn();
4646 Builder.ClearInsertionPoint();
4652 llvm::CallInst *TrapCall =
4654 TrapCall->setDoesNotReturn();
4655 TrapCall->setDoesNotThrow();
4658 Builder.ClearInsertionPoint();
4666 "Array to pointer decay must have array source type!");
4675 Addr =
Addr.withElementType(NewTy);
4681 "Expected pointer to array");
4687 Builder.CreateStructuredGEP(NewTy,
Addr.emitRawPointer(*
this), {});
4701 if (TBAAInfo) *TBAAInfo =
CGM.getTBAAAccessInfo(EltType);
4710 const auto *CE = dyn_cast<CastExpr>(E);
4711 if (!CE || CE->getCastKind() != CK_ArrayToPointerDecay)
4723 llvm::Type *elemType,
4729 const llvm::Twine &name =
"arrayidx") {
4730 if (inbounds && CGF.
getLangOpts().EmitLogicalPointer)
4731 return CGF.
Builder.CreateStructuredGEP(elemType, ptr, indices);
4745 llvm::Type *elementType,
bool inbounds,
4748 const llvm::Twine &name =
"arrayidx") {
4749 if (inbounds && CGF.
getLangOpts().EmitLogicalPointer)
4752 indices.drop_front()),
4753 elementType, align);
4774 return D && D->
hasAttr<BPFPreserveStaticOffsetAttr>();
4781 if (PointeeType.
isNull())
4794 llvm::Function *Fn =
4796 llvm::CallInst *
Call = CGF.
Builder.CreateCall(Fn, {
Addr.emitRawPointer(CGF)});
4814 if (
const auto *ME = dyn_cast<MemberExpr>(E))
4815 return ME->getMemberDecl()->hasAttr<BPFPreserveAccessIndexAttr>();
4817 if (
const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
4818 const auto *VarDef = dyn_cast<VarDecl>(DRE->getDecl());
4822 const auto *PtrT = VarDef->getType()->getAs<
PointerType>();
4828 if (
const auto *RecT = dyn_cast<RecordType>(PointeeT))
4829 return RecT->getDecl()
4830 ->getMostRecentDecl()
4831 ->
hasAttr<BPFPreserveAccessIndexAttr>();
4844 const llvm::Twine &name =
"arrayidx") {
4847 for (
auto *idx : indices.drop_back())
4866 llvm::Value *eltPtr;
4867 auto LastIndex = dyn_cast<llvm::ConstantInt>(indices.back());
4874 signedIndices, loc, eltAlign, name);
4878 unsigned idx = LastIndex->getZExtValue();
4879 llvm::DIType *DbgInfo =
nullptr;
4882 eltPtr = CGF.
Builder.CreatePreserveArrayAccessIndex(
4894struct StructFieldAccess
4895 :
public ConstStmtVisitor<StructFieldAccess, const Expr *> {
4896 const Expr *VisitCastExpr(
const CastExpr *E) {
4901 const Expr *VisitParenExpr(
const ParenExpr *E) {
4910 const FieldDecl *Field, int64_t &Offset) {
4913 unsigned FieldNo = 0;
4948 if (FD1OuterRec != FD2OuterRec)
4950 return std::optional<int64_t>();
4952 int64_t FD1Offset = 0;
4954 return std::optional<int64_t>();
4956 int64_t FD2Offset = 0;
4958 return std::optional<int64_t>();
4960 return std::make_optional<int64_t>(FD1Offset - FD2Offset);
4972 QualType IndexType, llvm::Value *IndexVal,
bool Accessed,
4973 bool FlexibleArray) {
4974 const auto *ME = dyn_cast<MemberExpr>(ArrayExpr->
IgnoreImpCasts());
4975 if (!ME || !ME->getMemberDecl()->getType()->isCountAttributedType())
4980 if (FlexibleArray &&
4981 !ME->isFlexibleArrayMemberLike(
getContext(), StrictFlexArraysLevel))
4989 if (std::optional<int64_t> Diff =
5004 ArrayInst =
Builder.CreatePointerBitCastOrAddrSpaceCast(ArrayInst,
5008 llvm::Value *BoundsVal =
5010 Builder.getInt32(*Diff),
".counted_by.gep");
5012 ".counted_by.load");
5016 CountFD->
getType(), Accessed);
5024 llvm::Value *IdxPre =
5026 bool SignedIndices =
false;
5027 auto EmitIdxAfterBase = [&, IdxPre](
bool Promote) -> llvm::Value * {
5030 assert(E->
getRHS() == E->
getIdx() &&
"index was neither LHS nor RHS");
5036 SignedIndices |= IdxSigned;
5038 if (
SanOpts.has(SanitizerKind::ArrayBounds))
5042 if (Promote && Idx->getType() !=
IntPtrTy)
5055 auto *Idx = EmitIdxAfterBase(
false);
5056 assert(LHS.
isSimple() &&
"Can only subscript lvalue vectors here!");
5064 std::optional<LValue> LV;
5067 LV =
CGM.getHLSLRuntime().emitResourceArraySubscriptExpr(E, *
this);
5069 LV =
CGM.getHLSLRuntime().emitBufferArraySubscriptExpr(E, *
this,
5081 auto *Idx = EmitIdxAfterBase(
true);
5088 CGM.getTBAAInfoForSubobject(LV, EltType));
5100 auto *Idx = EmitIdxAfterBase(
true);
5110 Idx =
Builder.CreateMul(Idx, numElements);
5112 Idx =
Builder.CreateNSWMul(Idx, numElements);
5124 auto *Idx = EmitIdxAfterBase(
true);
5127 llvm::Value *InterfaceSizeVal =
5128 llvm::ConstantInt::get(Idx->getType(), InterfaceSize.
getQuantity());
5130 llvm::Value *ScaledIdx =
Builder.CreateMul(Idx, InterfaceSizeVal);
5136 llvm::Type *OrigBaseElemTy =
Addr.getElementType();
5141 llvm::Value *EltPtr =
5143 ScaledIdx,
false, SignedIndices, E->
getExprLoc());
5150 assert(Array->getType()->isArrayType() &&
5151 "Array to pointer decay must have array source type!");
5155 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
5159 auto *Idx = EmitIdxAfterBase(
true);
5161 if (
SanOpts.has(SanitizerKind::ArrayBounds))
5169 *
this, ArrayLV.
getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
5173 if (!
CGM.getCodeGenOpts().NewStructPathTBAA) {
5176 EltTBAAInfo =
CGM.getTBAAInfoForSubobject(ArrayLV, E->
getType());
5181 EltTBAAInfo =
CGM.getTBAAAccessInfo(E->
getType());
5203 auto *Idx = EmitIdxAfterBase(
true);
5210 if (
SanOpts.has(SanitizerKind::ArrayBounds)) {
5211 StructFieldAccess Visitor;
5214 if (
const auto *CE = dyn_cast_if_present<CastExpr>(
Base);
5215 CE && CE->getCastKind() == CK_LValueToRValue)
5248 MatAddr =
CGM.getHLSLRuntime().createBufferMatrixTempAddress(
Base, *
this);
5258 "incomplete matrix subscript expressions should be rejected during Sema");
5264 llvm::MatrixBuilder MB(
Builder);
5267 unsigned NumRows = MatrixTy->getNumRows();
5268 bool IsMatrixRowMajor =
5270 llvm::Value *FinalIdx =
5271 MB.CreateIndex(RowIdx, ColIdx, NumRows, NumCols, IsMatrixRowMajor);
5282 bool IsLowerBound) {
5284 if (
auto *ASE = dyn_cast<ArraySectionExpr>(
Base->IgnoreParenImpCasts())) {
5288 BaseInfo = BaseLVal.getBaseInfo();
5293 Addr =
Addr.withElementType(NewTy);
5299 "Expected pointer to array");
5309 BaseInfo.mergeForCast(TypeBaseInfo);
5318 bool IsLowerBound) {
5321 "OpenACC Array section codegen not implemented");
5325 if (
auto *AT =
getContext().getAsArrayType(BaseTy))
5326 ResultExprTy = AT->getElementType();
5329 llvm::Value *Idx =
nullptr;
5337 LowerBound->getType()->hasSignedIntegerRepresentation());
5339 Idx = llvm::ConstantInt::getNullValue(
IntPtrTy);
5344 auto &
C =
CGM.getContext();
5346 llvm::APSInt ConstLength;
5349 if (std::optional<llvm::APSInt>
CL = Length->getIntegerConstantExpr(
C)) {
5356 if (std::optional<llvm::APSInt> LB =
5357 LowerBound->getIntegerConstantExpr(
C)) {
5359 LowerBound =
nullptr;
5364 else if (!LowerBound)
5367 if (Length || LowerBound) {
5368 auto *LowerBoundVal =
5372 LowerBound->getType()->hasSignedIntegerRepresentation())
5373 : llvm::ConstantInt::get(
IntPtrTy, ConstLowerBound);
5378 Length->getType()->hasSignedIntegerRepresentation())
5379 : llvm::ConstantInt::get(
IntPtrTy, ConstLength);
5380 Idx =
Builder.CreateAdd(LowerBoundVal, LengthVal,
"lb_add_len",
5383 if (Length && LowerBound) {
5385 Idx, llvm::ConstantInt::get(
IntPtrTy, 1),
"idx_sub_1",
5389 Idx = llvm::ConstantInt::get(
IntPtrTy, ConstLength + ConstLowerBound);
5395 if (
auto *VAT =
C.getAsVariableArrayType(ArrayTy)) {
5396 Length = VAT->getSizeExpr();
5397 if (std::optional<llvm::APSInt> L = Length->getIntegerConstantExpr(
C)) {
5402 auto *CAT =
C.getAsConstantArrayType(ArrayTy);
5403 assert(CAT &&
"unexpected type for array initializer");
5404 ConstLength = CAT->getSize();
5407 auto *LengthVal =
Builder.CreateIntCast(
5409 Length->getType()->hasSignedIntegerRepresentation());
5411 LengthVal, llvm::ConstantInt::get(
IntPtrTy, 1),
"len_sub_1",
5416 Idx = llvm::ConstantInt::get(
IntPtrTy, ConstLength);
5425 if (
auto *VLA =
getContext().getAsVariableArrayType(ResultExprTy)) {
5431 BaseTy, VLA->getElementType(), IsLowerBound);
5440 Idx =
Builder.CreateMul(Idx, NumElements);
5442 Idx =
Builder.CreateNSWMul(Idx, NumElements);
5451 assert(Array->getType()->isArrayType() &&
5452 "Array to pointer decay must have array source type!");
5456 if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(Array))
5463 *
this, ArrayLV.
getAddress(), {CGM.getSize(CharUnits::Zero()), Idx},
5464 ResultExprTy, !
getLangOpts().PointerOverflowDefined,
5467 TBAAInfo =
CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy);
5471 ResultExprTy, IsLowerBound);
5494 Base.getQuals().removeObjCGCAttr();
5503 "Result must be a vector");
5511 if (LTy->getScalarSizeInBits() > Vec->getType()->getScalarSizeInBits())
5512 Vec =
Builder.CreateZExt(Vec, LTy);
5513 Builder.CreateStore(Vec, VecMem);
5524 if (
Base.isSimple()) {
5525 llvm::Constant *CV =
5531 if (
Base.isMatrixRow()) {
5533 llvm::dyn_cast<llvm::ConstantInt>(
Base.getMatrixRowIdx())) {
5537 unsigned NumCols = Indices.size();
5539 unsigned Row = RowIdx->getZExtValue();
5543 QualType ElemQT = EVT->getElementType();
5546 for (
unsigned C = 0;
C < NumCols; ++
C) {
5547 unsigned Col = Indices[
C];
5548 unsigned Linear = Col * NumRows + Row;
5549 MatIndices.push_back(llvm::ConstantInt::get(
Int32Ty, Linear));
5552 llvm::Constant *ConstIdxs = llvm::ConstantVector::get(MatIndices);
5556 llvm::Constant *Cols =
5563 Base.getMatrixAddress(),
Base.getMatrixRowIdx(), Cols,
Base.getType(),
5567 assert(
Base.isExtVectorElt() &&
"Can only subscript lvalue vec elts here!");
5569 llvm::Constant *BaseElts =
Base.getExtVectorElts();
5572 for (
unsigned Index : Indices)
5573 CElts.push_back(BaseElts->getAggregateElement(Index));
5574 llvm::Constant *CV = llvm::ConstantVector::get(CElts);
5581 while (
auto *BaseMemberExpr = dyn_cast<MemberExpr>(UnderlyingBaseExpr))
5582 UnderlyingBaseExpr = BaseMemberExpr->getBase()->
IgnoreParens();
5595 return CGM.getHLSLRuntime().emitBufferMemberExpr(*
this, E);
5598 std::optional<LValue> LV;
5599 LV =
CGM.getHLSLRuntime().emitResourceMemberExpr(*
this, E);
5609 bool IsInBounds = !
getLangOpts().PointerOverflowDefined &&
5621 SkippedChecks.
set(SanitizerKind::Alignment,
true);
5623 SkippedChecks.
set(SanitizerKind::Null,
true);
5631 if (
auto *Field = dyn_cast<FieldDecl>(ND)) {
5639 CGM.getOpenMPRuntime().isNontemporalDecl(Field)) ||
5646 if (
const auto *FD = dyn_cast<FunctionDecl>(ND))
5649 llvm_unreachable(
"Unhandled member declaration!");
5656 llvm::Value *ThisValue) {
5657 bool HasExplicitObjectParameter =
false;
5658 const auto *MD = dyn_cast_if_present<CXXMethodDecl>(
CurCodeDecl);
5660 HasExplicitObjectParameter = MD->isExplicitObjectMemberFunction();
5661 assert(MD->getParent()->isLambda());
5662 assert(MD->getParent() == Field->getParent());
5665 if (HasExplicitObjectParameter) {
5667 auto It = LocalDeclMap.find(D);
5668 assert(It != LocalDeclMap.end() &&
"explicit parameter not loaded?");
5669 Address AddrOfExplicitObject = It->getSecond();
5680 if (ThisTy != LambdaTy) {
5683 LambdaLV.
getAddress(), ThisTy, BasePathArray.begin(),
5703 unsigned FieldIndex) {
5704 unsigned I = 0, Skipped = 0;
5707 if (I == FieldIndex)
5709 if (F->isUnnamedBitField())
5714 return FieldIndex - Skipped;
5724 if (Offset.isZero())
5746 llvm::Type *StructType =
5752 {CGF.Builder.getSize(idx)}),
5767 const FieldDecl *field,
bool IsInBounds) {
5794 if (RD->isDynamicClass())
5797 for (
const auto &
Base : RD->bases())
5817 CGM.getCodeGenOpts().AAPCSBitfieldWidth &&
5848 llvm::Type *FieldIntTy = llvm::Type::getIntNTy(
getLLVMContext(), SS);
5849 Addr =
Addr.withElementType(FieldIntTy);
5884 assert(!FieldTBAAInfo.
Offset &&
5885 "Nonzero offset for an access with no base type!");
5898 FieldTBAAInfo.
Size =
5905 if (
auto *ClassDef = dyn_cast<CXXRecordDecl>(rec)) {
5906 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
5907 ClassDef->isDynamicClass()) {
5921 if (
CGM.getCodeGenOpts().StrictVTablePointers &&
5925 addr =
Builder.CreateLaunderInvariantGroup(addr);
5968 if (field->
hasAttr<AnnotateAttr>())
5984 QualType FieldType = Field->getType();
5990 *
this,
Base.getAddress(), Field,
5995 V =
V.withElementType(llvmType);
6004 CGM.getTBAAInfoForSubobject(
Base, FieldType));
6047 assert(E->
isTransparent() &&
"non-transparent glvalue init list");
6055 const Expr *Operand) {
6056 if (
auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Operand->IgnoreParens())) {
6058 return std::nullopt;
6067std::optional<LValue> HandleConditionalOperatorLValueSimpleCase(
6069 const Expr *condExpr = E->
getCond();
6074 std::swap(Live, Dead);
6084 if (
auto *ThrowExpr = dyn_cast<CXXThrowExpr>(Live->
IgnoreParens())) {
6095 return std::nullopt;
6097struct ConditionalInfo {
6098 llvm::BasicBlock *lhsBlock, *rhsBlock;
6099 std::optional<LValue> LHS, RHS;
6104template<
typename FuncTy>
6106 const AbstractConditionalOperator *E,
6107 const FuncTy &BranchGenFunc) {
6123 Info.lhsBlock = CGF.
Builder.GetInsertBlock();
6126 CGF.
Builder.CreateBr(endBlock);
6134 Info.rhsBlock = CGF.
Builder.GetInsertBlock();
6146 "Unexpected conditional operator!");
6151 if (HandleConditionalOperatorLValueSimpleCase(*
this, E))
6154 EmitConditionalBlocks(*
this, E, [](CodeGenFunction &CGF,
const Expr *E) {
6161 if (!
expr->isGLValue()) {
6164 "Unexpected conditional operator!");
6169 if (std::optional<LValue> Res =
6170 HandleConditionalOperatorLValueSimpleCase(*
this,
expr))
6173 ConditionalInfo Info = EmitConditionalBlocks(
6174 *
this,
expr, [](CodeGenFunction &CGF,
const Expr *E) {
6178 if ((Info.LHS && !Info.LHS->isSimple()) ||
6179 (Info.RHS && !Info.RHS->isSimple()))
6182 if (Info.LHS && Info.RHS) {
6183 Address lhsAddr = Info.LHS->getAddress();
6184 Address rhsAddr = Info.RHS->getAddress();
6186 lhsAddr, rhsAddr, Info.lhsBlock, Info.rhsBlock,
6189 std::max(Info.LHS->getBaseInfo().getAlignmentSource(),
6190 Info.RHS->getBaseInfo().getAlignmentSource());
6192 Info.LHS->getTBAAInfo(), Info.RHS->getTBAAInfo());
6196 assert((Info.LHS || Info.RHS) &&
6197 "both operands of glvalue conditional are throw-expressions?");
6198 return Info.LHS ? *Info.LHS : *Info.RHS;
6210 llvm::scope_exit RestoreCurCast([
this, Prev =
CurCast] {
CurCast = Prev; });
6215 case CK_LValueToRValueBitCast:
6216 case CK_ArrayToPointerDecay:
6217 case CK_FunctionToPointerDecay:
6218 case CK_NullToMemberPointer:
6219 case CK_NullToPointer:
6220 case CK_IntegralToPointer:
6221 case CK_PointerToIntegral:
6222 case CK_PointerToBoolean:
6223 case CK_IntegralCast:
6224 case CK_BooleanToSignedIntegral:
6225 case CK_IntegralToBoolean:
6226 case CK_IntegralToFloating:
6227 case CK_FloatingToIntegral:
6228 case CK_FloatingToBoolean:
6229 case CK_FloatingCast:
6230 case CK_FloatingRealToComplex:
6231 case CK_FloatingComplexToReal:
6232 case CK_FloatingComplexToBoolean:
6233 case CK_FloatingComplexCast:
6234 case CK_FloatingComplexToIntegralComplex:
6235 case CK_IntegralRealToComplex:
6236 case CK_IntegralComplexToReal:
6237 case CK_IntegralComplexToBoolean:
6238 case CK_IntegralComplexCast:
6239 case CK_IntegralComplexToFloatingComplex:
6240 case CK_DerivedToBaseMemberPointer:
6241 case CK_BaseToDerivedMemberPointer:
6242 case CK_MemberPointerToBoolean:
6243 case CK_ReinterpretMemberPointer:
6244 case CK_AnyPointerToBlockPointerCast:
6245 case CK_ARCProduceObject:
6246 case CK_ARCConsumeObject:
6247 case CK_ARCReclaimReturnedObject:
6248 case CK_ARCExtendBlockObject:
6249 case CK_CopyAndAutoreleaseBlockObject:
6250 case CK_IntToOCLSampler:
6251 case CK_FloatingToFixedPoint:
6252 case CK_FixedPointToFloating:
6253 case CK_FixedPointCast:
6254 case CK_FixedPointToBoolean:
6255 case CK_FixedPointToIntegral:
6256 case CK_IntegralToFixedPoint:
6258 case CK_HLSLVectorTruncation:
6259 case CK_HLSLMatrixTruncation:
6260 case CK_HLSLArrayRValue:
6261 case CK_HLSLElementwiseCast:
6262 case CK_HLSLAggregateSplatCast:
6266 llvm_unreachable(
"dependent cast kind in IR gen!");
6268 case CK_BuiltinFnToFnPtr:
6269 llvm_unreachable(
"builtin functions are handled elsewhere");
6272 case CK_NonAtomicToAtomic:
6273 case CK_AtomicToNonAtomic:
6283 case CK_ConstructorConversion:
6284 case CK_UserDefinedConversion:
6285 case CK_CPointerToObjCPointerCast:
6286 case CK_BlockPointerToObjCPointerCast:
6287 case CK_LValueToRValue:
6302 if (
V.getElementType() !=
T)
6309 case CK_UncheckedDerivedToBase:
6310 case CK_DerivedToBase: {
6324 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6328 case CK_BaseToDerived: {
6343 if (
SanOpts.has(SanitizerKind::CFIDerivedCast))
6349 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6351 case CK_LValueBitCast: {
6355 CGM.EmitExplicitCastExprType(CE,
this);
6360 if (
SanOpts.has(SanitizerKind::CFIUnrelatedCast))
6366 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6368 case CK_AddressSpaceConversion: {
6377 case CK_ObjCObjectLValueCast: {
6381 CGM.getTBAAInfoForSubobject(LV, E->
getType()));
6383 case CK_ZeroToOCLOpaqueType:
6384 llvm_unreachable(
"NULL to OpenCL opaque type lvalue cast is not valid");
6386 case CK_VectorSplat: {
6394 llvm_unreachable(
"Unhandled lvalue cast kind?");
6402std::pair<LValue, LValue>
6422 return std::make_pair(BaseLV, TempLV);
6430 llvm::Value *
Addr = TempLV.getAddress().getBasePointer();
6433 Address TmpAddr(
Addr, ElTy, TempLV.getAlignment());
6443 llvm::DenseMap<const OpaqueValueExpr*,LValue>::iterator
6444 it = OpaqueLValues.find(e);
6446 if (it != OpaqueLValues.end())
6449 assert(e->
isUnique() &&
"LValue for a nonunique OVE hasn't been emitted");
6457 llvm::DenseMap<const OpaqueValueExpr*,RValue>::iterator
6458 it = OpaqueRValues.find(e);
6460 if (it != OpaqueRValues.end())
6463 assert(e->
isUnique() &&
"RValue for a nonunique OVE hasn't been emitted");
6469 return OpaqueLValues.contains(E);
6470 return OpaqueRValues.contains(E);
6494 llvm_unreachable(
"bad evaluation kind");
6503 llvm::CallBase **CallOrInvoke) {
6504 llvm::CallBase *CallOrInvokeStorage;
6505 if (!CallOrInvoke) {
6506 CallOrInvoke = &CallOrInvokeStorage;
6509 llvm::scope_exit AddCoroElideSafeOnExit([&] {
6511 auto *I = *CallOrInvoke;
6513 I->addFnAttr(llvm::Attribute::CoroElideSafe);
6521 if (
const auto *CE = dyn_cast<CXXMemberCallExpr>(E))
6524 if (
const auto *CE = dyn_cast<CUDAKernelCallExpr>(E))
6529 if (
const auto *CE = dyn_cast<CXXOperatorCallExpr>(E))
6530 if (
const auto *MD =
6531 dyn_cast_if_present<CXXMethodDecl>(CE->getCalleeDecl());
6532 MD && MD->isImplicitObjectMemberFunction())
6547 nullptr, CallOrInvoke);
6553 llvm::CallBase **CallOrInvoke) {
6556 nullptr, CallOrInvoke);
6564 if (!PD->isInlineBuiltinDeclaration())
6573 std::string NoBuiltinFD = (
"no-builtin-" + FD->
getName()).str();
6574 std::string NoBuiltins =
"no-builtins";
6577 std::string FDInlineName = (Ident +
".inline").str();
6579 bool IsPredefinedLibFunction =
6581 bool HasAttributeNoBuiltin =
6582 CGF.
CurFn->getAttributes().hasFnAttr(NoBuiltinFD) ||
6583 CGF.
CurFn->getAttributes().hasFnAttr(NoBuiltins);
6587 if (CGF.
CurFn->getName() != FDInlineName &&
6590 llvm::Function *Fn = llvm::cast<llvm::Function>(CalleePtr);
6591 llvm::Module *M = Fn->getParent();
6592 llvm::Function *Clone = M->getFunction(FDInlineName);
6594 Clone = llvm::Function::Create(Fn->getFunctionType(),
6595 llvm::GlobalValue::InternalLinkage,
6596 Fn->getAddressSpace(), FDInlineName, M);
6597 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
6608 else if (!IsPredefinedLibFunction || !HasAttributeNoBuiltin)
6614 FD->
hasAttr<CUDAGlobalAttr>())
6622 if (DeviceKernelAttr::isOpenCLSpelling(FD->
getAttr<DeviceKernelAttr>()))
6635 auto ConvertFuncrefToPtr = [&](llvm::Value *CalleePtr) -> llvm::Value * {
6636 if (
auto *TET = dyn_cast<llvm::TargetExtType>(CalleePtr->getType());
6637 TET && TET->getName() ==
"wasm.funcref") {
6638 llvm::Function *ToPtr =
6639 CGM.getIntrinsic(llvm::Intrinsic::wasm_funcref_to_ptr);
6640 return Builder.CreateCall(ToPtr, {CalleePtr});
6646 if (
auto ICE = dyn_cast<ImplicitCastExpr>(E)) {
6647 if (ICE->getCastKind() == CK_FunctionToPointerDecay ||
6648 ICE->getCastKind() == CK_BuiltinFnToFnPtr) {
6654 if (ICE->getCastKind() == CK_LValueToRValue) {
6655 const Expr *SubExpr = ICE->getSubExpr();
6657 std::pair<llvm::Value *, CGPointerAuthInfo>
Result =
6664 if (
const auto *VD =
6677 }
else if (
auto DRE = dyn_cast<DeclRefExpr>(E)) {
6678 if (
auto FD = dyn_cast<FunctionDecl>(DRE->getDecl())) {
6681 }
else if (
auto ME = dyn_cast<MemberExpr>(E)) {
6682 if (
auto FD = dyn_cast<FunctionDecl>(ME->getMemberDecl())) {
6688 }
else if (
auto NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
6692 }
else if (
auto PDE = dyn_cast<CXXPseudoDestructorExpr>(E)) {
6697 llvm::Value *calleePtr;
6709 if (
const auto *VD =
6715 CGCallee callee(calleeInfo, ConvertFuncrefToPtr(calleePtr), pointerAuth);
6731 assert(E->
getOpcode() == BO_Assign &&
"unexpected binary l-value");
6794 llvm::Value *
Result =
nullptr;
6797 if (
SanOpts.has(SanitizerKind::ImplicitBitfieldConversion))
6812 CGM.getOpenMPRuntime().checkAndEmitLastprivateConditional(*
this,
6829 llvm_unreachable(
"bad evaluation kind");
6845 if (
CGM.getHLSLRuntime().emitGlobalResourceArray(*
this, E->
getRHS(), Slot))
6857 llvm::CallBase **CallOrInvoke) {
6865 "Can't have a scalar return unless the return type is a "
6878 &&
"binding l-value to type which needs a temporary");
6916 "Can't have a scalar return unless the return type is a "
6930 return CGM.getObjCRuntime().EmitIvarOffset(*
this,
Interface, Ivar);
6938 return Builder.CreateZExtOrTrunc(OffsetValue,
6943 llvm::Value *BaseValue,
6945 unsigned CVRQualifiers) {
6946 return CGM.getObjCRuntime().EmitObjCValueForIvar(*
this, ObjectTy, BaseValue,
6947 Ivar, CVRQualifiers);
6952 llvm::Value *BaseValue =
nullptr;
6963 ObjectTy = BaseExpr->
getType();
6985 llvm::CallBase **CallOrInvoke,
6990 "Call must have function pointer type!");
6992 const Decl *TargetDecl =
6995 assert((!isa_and_present<FunctionDecl>(TargetDecl) ||
6997 "trying to emit a call to an immediate function");
7007 if (
SanOpts.has(SanitizerKind::Function) &&
7010 if (llvm::Constant *PrefixSig =
7011 CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(
CGM)) {
7012 auto CheckOrdinal = SanitizerKind::SO_Function;
7013 auto CheckHandler = SanitizerHandler::FunctionTypeMismatch;
7017 llvm::Type *PrefixSigType = PrefixSig->getType();
7018 llvm::StructType *PrefixStructTy = llvm::StructType::get(
7019 CGM.getLLVMContext(), {PrefixSigType, Int32Ty},
true);
7021 llvm::Value *CalleePtr = Callee.getFunctionPointer();
7022 if (
CGM.getCodeGenOpts().PointerAuth.FunctionPointers) {
7025 Address(CalleePtr, CalleePtr->getType(),
7027 CalleePtr->getPointerAlignment(
CGM.getDataLayout())),
7028 Callee.getPointerAuthInfo(),
nullptr);
7029 CalleePtr =
Addr.emitRawPointer(*
this);
7041 llvm::Value *AlignedCalleePtr;
7042 if (
CGM.getTriple().isARM() ||
CGM.getTriple().isThumb()) {
7043 AlignedCalleePtr =
Builder.CreateIntrinsic(
7044 CalleePtr->getType(), llvm::Intrinsic::ptrmask,
7045 {CalleePtr, llvm::ConstantInt::getSigned(IntPtrTy, ~1)});
7047 AlignedCalleePtr = CalleePtr;
7050 llvm::Value *CalleePrefixStruct = AlignedCalleePtr;
7051 llvm::Value *CalleeSigPtr =
7052 Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 0);
7053 llvm::Value *CalleeSig =
7055 llvm::Value *CalleeSigMatch =
Builder.CreateICmpEQ(CalleeSig, PrefixSig);
7059 Builder.CreateCondBr(CalleeSigMatch, TypeCheck, Cont);
7062 llvm::Value *CalleeTypeHash =
Builder.CreateAlignedLoad(
7064 Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 1),
7066 llvm::Value *CalleeTypeHashMatch =
7067 Builder.CreateICmpEQ(CalleeTypeHash, TypeHash);
7070 EmitCheck(std::make_pair(CalleeTypeHashMatch, CheckOrdinal), CheckHandler,
7071 StaticData, {CalleePtr});
7080 if (
const auto *FD = dyn_cast_or_null<FunctionDecl>(TargetDecl);
7081 FD && DeviceKernelAttr::isOpenCLSpelling(FD->getAttr<DeviceKernelAttr>()))
7082 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FnType);
7086 if (
SanOpts.has(SanitizerKind::CFIICall) &&
7088 auto CheckOrdinal = SanitizerKind::SO_CFIICall;
7089 auto CheckHandler = SanitizerHandler::CFICheckFail;
7093 llvm::Metadata *MD =
7094 CGM.CreateMetadataIdentifierForFnType(
QualType(FnType, 0));
7096 llvm::Value *TypeId = llvm::MetadataAsValue::get(
getLLVMContext(), MD);
7098 llvm::Value *CalleePtr = Callee.getFunctionPointer();
7099 llvm::Value *TypeTest =
Builder.CreateCall(
7100 CGM.getIntrinsic(llvm::Intrinsic::type_test), {CalleePtr, TypeId});
7102 auto CrossDsoTypeId =
CGM.CreateCrossDsoCfiTypeId(MD);
7103 llvm::Constant *StaticData[] = {
7108 if (
CGM.getCodeGenOpts().SanitizeCfiCrossDso && CrossDsoTypeId) {
7112 EmitCheck(std::make_pair(TypeTest, CheckOrdinal), CheckHandler,
7113 StaticData, {CalleePtr, llvm::UndefValue::get(
IntPtrTy)});
7128 bool StaticOperator =
false;
7129 if (
auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
7130 if (OCE->isAssignmentOp())
7133 switch (OCE->getOperator()) {
7135 case OO_GreaterGreater:
7147 if (
const auto *MD =
7148 dyn_cast_if_present<CXXMethodDecl>(OCE->getCalleeDecl());
7149 MD && MD->isStatic())
7150 StaticOperator =
true;
7154 if (StaticOperator) {
7158 Arguments = drop_begin(Arguments, 1);
7160 EmitCallArgs(Args, dyn_cast<FunctionProtoType>(FnType), Arguments,
7167 *ResolvedFnInfo = &FnInfo;
7172 if (
CGM.getLangOpts().HIP && !
CGM.getLangOpts().CUDAIsDevice &&
7175 llvm::Value *Handle = Callee.getFunctionPointer();
7177 Address(Handle, Handle->getType(),
CGM.getPointerAlign()));
7178 Callee.setFunctionPointer(
Stub);
7185 if (
getLangOpts().OpenMPIsTargetDevice &&
CGM.getTriple().isGPU() &&
7189 while (CalleeExpr) {
7190 if ((DRE = dyn_cast<DeclRefExpr>(CalleeExpr)))
7192 if (
const auto *ME = dyn_cast<MemberExpr>(CalleeExpr))
7194 else if (
const auto *ASE = dyn_cast<ArraySubscriptExpr>(CalleeExpr))
7200 const auto *VD = DRE ? dyn_cast<VarDecl>(DRE->
getDecl()) :
nullptr;
7201 if (VD && VD->hasAttr<OMPTargetIndirectCallAttr>()) {
7202 auto *FuncPtrTy = llvm::PointerType::get(
7203 CGM.getLLVMContext(),
CGM.getDataLayout().getProgramAddressSpace());
7204 llvm::Type *RtlFnArgs[] = {FuncPtrTy};
7205 llvm::FunctionCallee DeviceRtlFn =
CGM.CreateRuntimeFunction(
7206 llvm::FunctionType::get(FuncPtrTy, RtlFnArgs,
false),
7207 "__llvm_omp_indirect_call_lookup");
7208 llvm::Value *
Func = Callee.getFunctionPointer();
7209 llvm::Type *BackupTy =
Func->getType();
7213 Callee.setFunctionPointer(
Func);
7217 llvm::CallBase *LocalCallOrInvoke =
nullptr;
7221 if (
auto *CalleeDecl = dyn_cast_or_null<FunctionDecl>(TargetDecl)) {
7222 if (CalleeDecl->hasAttr<RestrictAttr>() ||
7223 CalleeDecl->hasAttr<MallocSpanAttr>() ||
7224 CalleeDecl->hasAttr<AllocSizeAttr>()) {
7226 if (
SanOpts.has(SanitizerKind::AllocToken)) {
7233 *CallOrInvoke = LocalCallOrInvoke;
7252 bool IsInBounds = !
getLangOpts().PointerOverflowDefined &&
7255 E, BaseAddr, OffsetV, MPT, IsInBounds, &BaseInfo, &TBAAInfo);
7257 return MakeAddrLValue(MemberAddr, MPT->getPointeeType(), BaseInfo, TBAAInfo);
7274 llvm_unreachable(
"bad evaluation kind");
7278 assert(Val->getType()->isFPOrFPVectorTy());
7283 llvm::MDNode *Node = MDHelper.createFPMath(Accuracy);
7289 llvm::Type *EltTy = Val->getType()->getScalarType();
7290 if (!EltTy->isFloatTy() && !EltTy->isHalfTy())
7294 !
CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) ||
7296 !
CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) {
7311 llvm::Type *EltTy = Val->getType()->getScalarType();
7312 if (!EltTy->isFloatTy() && !EltTy->isHalfTy())
7316 !
CGM.getCodeGenOpts().OpenCLCorrectlyRoundedDivSqrt) ||
7318 !
CGM.getCodeGenOpts().HIPCorrectlyRoundedDivSqrt)) {
7333 struct LValueOrRValue {
7347 LValueOrRValue result;
7351 const Expr *semantic = *i;
7355 if (
const auto *ov = dyn_cast<OpaqueValueExpr>(semantic)) {
7357 if (ov->isUnique()) {
7358 assert(ov != resultExpr &&
7359 "A unique OVE cannot be used as the result expression");
7367 if (ov == resultExpr && ov->
isPRValue() && !forLValue &&
7372 opaqueData = OVMA::bind(CGF, ov, LV);
7377 opaqueData = OVMA::bind(CGF, ov, ov->getSourceExpr());
7380 if (ov == resultExpr) {
7388 opaques.push_back(opaqueData);
7392 }
else if (semantic == resultExpr) {
7424 std::tuple<LValue, QualType, llvm::SmallVector<llvm::Value *, 4>>, 16>
7426 llvm::IntegerType *IdxTy = llvm::IntegerType::get(
getLLVMContext(), 32);
7427 WorkList.push_back({Val, Val.
getType(), {llvm::ConstantInt::get(IdxTy, 0)}});
7429 while (!WorkList.empty()) {
7430 auto [LVal,
T, IdxList] = WorkList.pop_back_val();
7431 T =
T.getCanonicalType().getUnqualifiedType();
7432 if (
const auto *CAT = dyn_cast<ConstantArrayType>(
T)) {
7433 uint64_t Size = CAT->getZExtSize();
7434 for (int64_t I = Size - 1; I > -1; I--) {
7436 IdxListCopy.push_back(llvm::ConstantInt::get(IdxTy, I));
7437 WorkList.emplace_back(LVal, CAT->getElementType(), IdxListCopy);
7439 }
else if (
const auto *RT = dyn_cast<RecordType>(
T)) {
7441 assert(!
Record->isUnion() &&
"Union types not supported in flat cast.");
7446 std::tuple<LValue, QualType, llvm::SmallVector<llvm::Value *, 4>>, 16>
7455 "HLSL doesn't support multiple inheritance.");
7458 IdxListCopy.push_back(llvm::ConstantInt::get(
7460 ReverseList.emplace_back(LVal,
Base->getType(), IdxListCopy);
7469 bool createdGEP =
false;
7470 for (
auto *FD :
Record->fields()) {
7471 if (FD->isBitField()) {
7472 if (FD->isUnnamedBitField())
7476 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList,
7477 LLVMT, Align,
"gep");
7481 ReverseList.push_back({FieldLVal, FD->
getType(), {}});
7484 IdxListCopy.push_back(
7486 ReverseList.emplace_back(LVal, FD->getType(), IdxListCopy);
7490 std::reverse(ReverseList.begin(), ReverseList.end());
7491 llvm::append_range(WorkList, ReverseList);
7492 }
else if (
const auto *VT = dyn_cast<VectorType>(
T)) {
7495 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList, LLVMT,
7496 Align,
"vector.gep");
7498 for (
unsigned I = 0, E = VT->getNumElements(); I < E; I++) {
7499 llvm::Constant *Idx = llvm::ConstantInt::get(IdxTy, I);
7503 AccessList.emplace_back(LV);
7505 }
else if (
const auto *MT = dyn_cast<ConstantMatrixType>(
T)) {
7513 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList, LLVMT,
7514 Align,
"matrix.gep");
7517 unsigned NumRows = MT->getNumRows();
7518 unsigned NumCols = MT->getNumColumns();
7520 llvm::MatrixBuilder MB(
Builder);
7521 for (
unsigned Row = 0; Row < MT->getNumRows(); Row++) {
7522 for (
unsigned Col = 0; Col < MT->getNumColumns(); Col++) {
7523 llvm::Value *RowIdx = llvm::ConstantInt::get(IdxTy, Row);
7524 llvm::Value *ColIdx = llvm::ConstantInt::get(IdxTy, Col);
7525 llvm::Value *Idx = MB.CreateIndex(RowIdx, ColIdx, NumRows, NumCols,
7530 AccessList.emplace_back(LV);
7534 if (!IdxList.empty()) {
7537 Address GEP =
Builder.CreateInBoundsGEP(LVal.getAddress(), IdxList,
7538 LLVMT, Align,
"gep");
7541 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 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 bool OnlyHasInlineBuiltinDeclaration(const FunctionDecl *FD)
static LValue EmitGlobalVarDeclLValue(CodeGenFunction &CGF, const Expr *E, const VarDecl *VD)
static bool hasAnyVptr(const QualType Type, const ASTContext &Context)
static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase)
Given an array base, check whether its member access belongs to a record with preserve_access_index a...
static Address emitDeclTargetVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType T)
VariableTypeDescriptorKind
@ TK_Float
A floating-point type.
@ TK_Unknown
Any other type. The value representation is unspecified.
@ TK_Integer
An integer type.
@ TK_BitInt
An _BitInt(N) type.
static void EmitStoreOfMatrixScalar(llvm::Value *value, LValue lvalue, bool isInit, CodeGenFunction &CGF)
static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo, KnownNonNull_t IsKnownNonNull, CodeGenFunction &CGF)
static Address emitPreserveStructAccess(CodeGenFunction &CGF, LValue base, Address addr, const FieldDecl *field)
const SanitizerHandlerInfo SanitizerHandlers[]
static void emitCheckHandlerCall(CodeGenFunction &CGF, llvm::FunctionType *FnType, ArrayRef< llvm::Value * > FnArgs, SanitizerHandler CheckHandler, CheckRecoverableKind RecoverKind, bool IsFatal, llvm::BasicBlock *ContBB, bool NoMerge)
static Address emitOMPArraySectionBase(CodeGenFunction &CGF, const Expr *Base, LValueBaseInfo &BaseInfo, TBAAAccessInfo &TBAAInfo, QualType BaseTy, QualType ElTy, bool IsLowerBound)
static mlir::Value emitPointerArithmetic(CIRGenFunction &cgf, const BinOpInfo &op, bool isSubtraction)
Emit pointer + index arithmetic.
static Address createReferenceTemporary(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *inner)
static CharUnits getArrayElementAlign(CharUnits arrayAlign, mlir::Value idx, CharUnits eltSize)
static void pushTemporaryCleanup(CIRGenFunction &cgf, const MaterializeTemporaryExpr *m, const Expr *e, Address referenceTemporary)
static QualType getFixedSizeElementType(const ASTContext &astContext, const VariableArrayType *vla)
static bool canEmitSpuriousReferenceToVariable(CIRGenFunction &cgf, const DeclRefExpr *e, const VarDecl *vd)
Determine whether we can emit a reference to vd from the current context, despite not necessarily hav...
static DeclRefExpr * tryToConvertMemberExprToDeclRefExpr(CIRGenFunction &cgf, const MemberExpr *me)
static 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 fixed int type of a specified bitwidth.
unsigned getNumBits() const
bool isPredefinedLibFunction(unsigned ID) const
Determines whether this builtin is a predefined libc/libm function, such as "malloc",...
Represents binding an expression to a temporary.
CXXTemporary * getTemporary()
const Expr * getSubExpr() const
Represents a call to a C++ constructor.
Represents a C++ destructor within a class.
Represents a C++ struct/union/class.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool isStandardLayout() const
Determine whether this class is standard-layout per C++ [class]p7.
unsigned getNumBases() const
Retrieves the number of base classes of this class.
base_class_iterator bases_begin()
bool isDynamicClass() const
bool hasDefinition() const
const CXXRecordDecl * getStandardLayoutBaseWithFields() const
If this is a standard-layout class or union, any and all data members will be declared in the same ty...
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
MSGuidDecl * getGuidDecl() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCoroElideSafe() const
QualType getCallReturnType(const ASTContext &Ctx) const
getCallReturnType - Get the return type of the call expr.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
path_iterator path_begin()
CastKind getCastKind() const
bool changesVolatileQualification() const
Return.
CharUnits - This is an opaque type for sizes expressed in character units.
CharUnits alignmentAtOffset(CharUnits offset) const
Given that this is a non-zero alignment value, what is the alignment at the given offset?
llvm::MaybeAlign getAsMaybeAlign() const
getAsMaybeAlign - Returns Quantity as a valid llvm::Align or std::nullopt, Beware llvm::MaybeAlign as...
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
@ None
Trap Messages are omitted.
@ Detailed
Trap Message includes more context (e.g.
@ 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 void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
virtual LValue EmitThreadLocalVarDeclLValue(CodeGenFunction &CGF, const VarDecl *VD, QualType LValType)=0
Emit a reference to a non-local thread_local variable (including triggering the initialization of all...
virtual bool usesThreadWrapperFunction(const VarDecl *VD) const =0
Abstract information about a function or function prototype.
const GlobalDecl getCalleeDecl() const
All available information about a concrete callee.
CGCalleeInfo getAbstractInfo() const
const CXXPseudoDestructorExpr * getPseudoDestructorExpr() const
bool isPseudoDestructor() const
static CGCallee forBuiltin(unsigned builtinID, const FunctionDecl *builtinDecl)
unsigned getBuiltinID() const
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
const FunctionDecl * getBuiltinDecl() const
static CGCallee forPseudoDestructor(const CXXPseudoDestructorExpr *E)
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)
Emit standalone debug info for a type.
llvm::DILocation * CreateTrapFailureMessageFor(llvm::DebugLoc TrapLocation, StringRef Category, StringRef FailureMsg)
Create a debug location from TrapLocation that adds an artificial inline frame where the frame name i...
llvm::DIType * getOrCreateRecordType(QualType Ty, SourceLocation L)
Emit record type's standalone debug info.
CGFunctionInfo - Class to encapsulate the information about a function definition.
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)
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.
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()
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.
FunctionDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
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.
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
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,...
__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