38#include "llvm/ADT/ArrayRef.h"
39#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/Dominators.h"
42#include "llvm/IR/FPEnv.h"
43#include "llvm/IR/Instruction.h"
44#include "llvm/IR/IntrinsicInst.h"
45#include "llvm/IR/Intrinsics.h"
46#include "llvm/IR/MDBuilder.h"
47#include "llvm/Support/CRC.h"
48#include "llvm/Support/xxhash.h"
49#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
50#include "llvm/Transforms/Utils/PromoteMemToReg.h"
54using namespace CodeGen;
64 if (CGOpts.DisableLifetimeMarkers)
68 if (CGOpts.SanitizeAddressUseAfterScope ||
74 return CGOpts.OptimizationLevel != 0;
77CodeGenFunction::CodeGenFunction(
CodeGenModule &cgm,
bool suppressNewContext)
79 Builder(cgm, cgm.getModule().getContext(),
llvm::ConstantFolder(),
81 SanOpts(CGM.getLangOpts().Sanitize), CurFPFeatures(CGM.getLangOpts()),
82 DebugInfo(CGM.getModuleDebugInfo()), PGO(cgm),
83 ShouldEmitLifetimeMarkers(
85 if (!suppressNewContext)
86 CGM.getCXXABI().getMangleContext().startNewFunction();
89 SetFastMathFlags(CurFPFeatures);
92CodeGenFunction::~CodeGenFunction() {
95 "missed to deactivate a cleanup");
111llvm::fp::ExceptionBehavior
119 llvm_unreachable(
"Unsupported FP Exception Behavior");
124 llvm::FastMathFlags FMF;
125 FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
126 FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
127 FMF.setNoInfs(FPFeatures.getNoHonorInfs());
128 FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
129 FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
130 FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
144 ConstructorHelper(FPFeatures);
147void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(
FPOptions FPFeatures) {
148 OldFPFeatures = CGF.CurFPFeatures;
149 CGF.CurFPFeatures = FPFeatures;
151 OldExcept = CGF.Builder.getDefaultConstrainedExcept();
152 OldRounding = CGF.Builder.getDefaultConstrainedRounding();
154 if (OldFPFeatures == FPFeatures)
157 FMFGuard.emplace(CGF.Builder);
160 CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
161 auto NewExceptionBehavior =
164 CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
166 CGF.SetFastMathFlags(FPFeatures);
168 assert((CGF.CurFuncDecl ==
nullptr || CGF.Builder.getIsFPConstrained() ||
169 isa<CXXConstructorDecl>(CGF.CurFuncDecl) ||
170 isa<CXXDestructorDecl>(CGF.CurFuncDecl) ||
171 (NewExceptionBehavior == llvm::fp::ebIgnore &&
172 NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
173 "FPConstrained should be enabled on entire function");
175 auto mergeFnAttrValue = [&](StringRef Name,
bool Value) {
177 CGF.CurFn->getFnAttribute(Name).getValueAsBool();
178 auto NewValue = OldValue &
Value;
179 if (OldValue != NewValue)
180 CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));
182 mergeFnAttrValue(
"no-infs-fp-math", FPFeatures.getNoHonorInfs());
183 mergeFnAttrValue(
"no-nans-fp-math", FPFeatures.getNoHonorNaNs());
184 mergeFnAttrValue(
"no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
187 FPFeatures.getAllowFPReassociate() && FPFeatures.getAllowReciprocal() &&
188 FPFeatures.getAllowApproxFunc() && FPFeatures.getNoSignedZero() &&
193 CGF.CurFPFeatures = OldFPFeatures;
194 CGF.Builder.setDefaultConstrainedExcept(OldExcept);
195 CGF.Builder.setDefaultConstrainedRounding(OldRounding);
209 nullptr, IsKnownNonNull)
217 return ::makeNaturalAlignAddrLValue(
V,
T,
false,
224 return ::makeNaturalAlignAddrLValue(
V,
T,
true,
230 return ::makeNaturalAlignAddrLValue(
V,
T,
false,
236 return ::makeNaturalAlignAddrLValue(
V,
T,
true,
249 llvm::Type *LLVMTy) {
256 switch (
type->getTypeClass()) {
257#define TYPE(name, parent)
258#define ABSTRACT_TYPE(name, parent)
259#define NON_CANONICAL_TYPE(name, parent) case Type::name:
260#define DEPENDENT_TYPE(name, parent) case Type::name:
261#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
262#include "clang/AST/TypeNodes.inc"
263 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
266 case Type::DeducedTemplateSpecialization:
267 llvm_unreachable(
"undeduced type in IR-generation");
272 case Type::BlockPointer:
273 case Type::LValueReference:
274 case Type::RValueReference:
275 case Type::MemberPointer:
277 case Type::ExtVector:
278 case Type::ConstantMatrix:
279 case Type::FunctionProto:
280 case Type::FunctionNoProto:
282 case Type::ObjCObjectPointer:
285 case Type::HLSLAttributedResource:
293 case Type::ConstantArray:
294 case Type::IncompleteArray:
295 case Type::VariableArray:
297 case Type::ObjCObject:
298 case Type::ObjCInterface:
299 case Type::ArrayParameter:
304 type = cast<AtomicType>(
type)->getValueType();
307 llvm_unreachable(
"unknown type kind!");
314 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
317 assert(!CurBB->getTerminator() &&
"Unexpected terminated block.");
327 return llvm::DebugLoc();
334 llvm::BranchInst *BI =
336 if (BI && BI->isUnconditional() &&
340 llvm::DebugLoc
Loc = BI->getDebugLoc();
341 Builder.SetInsertPoint(BI->getParent());
342 BI->eraseFromParent();
354 return llvm::DebugLoc();
359 if (!BB->use_empty()) {
367 assert(BreakContinueStack.empty() &&
368 "mismatched push/pop in break/continue stack!");
370 "mismatched push/pop of cleanups in EHStack!");
372 "mismatched activate/deactivate of cleanups!");
377 "mismatched push/pop in convergence stack!");
380 bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
381 && NumSimpleReturnExprs == NumReturnExprs
396 if (OnlySimpleReturnStmts)
397 DI->EmitLocation(
Builder, LastStopPoint);
399 DI->EmitLocation(
Builder, EndLoc);
407 bool HasOnlyNoopCleanups =
409 bool EmitRetDbgLoc = !HasCleanups || HasOnlyNoopCleanups;
411 std::optional<ApplyDebugLocation> OAL;
416 if (OnlySimpleReturnStmts)
417 DI->EmitLocation(
Builder, EndLoc);
432 CurFn->addFnAttr(
"instrument-function-exit",
"__cyg_profile_func_exit");
434 CurFn->addFnAttr(
"instrument-function-exit-inlined",
435 "__cyg_profile_func_exit");
449 "did not remove all scopes from cleanup stack!");
453 if (IndirectBranch) {
460 if (!EscapedLocals.empty()) {
464 EscapeArgs.resize(EscapedLocals.size());
465 for (
auto &Pair : EscapedLocals)
466 EscapeArgs[Pair.second] = Pair.first;
467 llvm::Function *FrameEscapeFn = llvm::Intrinsic::getOrInsertDeclaration(
475 Ptr->eraseFromParent();
479 if (PostAllocaInsertPt) {
480 llvm::Instruction *PostPtr = PostAllocaInsertPt;
481 PostAllocaInsertPt =
nullptr;
482 PostPtr->eraseFromParent();
487 if (IndirectBranch) {
488 llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
489 if (PN->getNumIncomingValues() == 0) {
490 PN->replaceAllUsesWith(llvm::PoisonValue::get(PN->getType()));
491 PN->eraseFromParent();
500 for (
const auto &FuncletAndParent : TerminateFunclets)
506 for (
const auto &R : DeferredReplacements) {
507 if (llvm::Value *Old = R.first) {
508 Old->replaceAllUsesWith(R.second);
509 cast<llvm::Instruction>(Old)->eraseFromParent();
512 DeferredReplacements.clear();
521 llvm::DominatorTree DT(*
CurFn);
522 llvm::PromoteMemToReg(
528 for (llvm::Argument &A :
CurFn->args())
529 if (
auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
531 std::max((uint64_t)LargestVectorWidth,
532 VT->getPrimitiveSizeInBits().getKnownMinValue());
535 if (
auto *VT = dyn_cast<llvm::VectorType>(
CurFn->getReturnType()))
537 std::max((uint64_t)LargestVectorWidth,
538 VT->getPrimitiveSizeInBits().getKnownMinValue());
550 if (
getContext().getTargetInfo().getTriple().isX86())
551 CurFn->addFnAttr(
"min-legal-vector-width",
552 llvm::utostr(LargestVectorWidth));
562 if (RetAlloca && RetAlloca->use_empty()) {
563 RetAlloca->eraseFromParent();
616 llvm::raw_string_ostream Out(Mangled);
618 return llvm::ConstantInt::get(
622void CodeGenFunction::EmitKernelMetadata(
const FunctionDecl *FD,
623 llvm::Function *Fn) {
624 if (!FD->
hasAttr<OpenCLKernelAttr>() && !FD->
hasAttr<CUDAGlobalAttr>())
633 getContext().getTargetInfo().getTriple().isSPIRV())))
636 if (
const VecTypeHintAttr *A = FD->
getAttr<VecTypeHintAttr>()) {
637 QualType HintQTy = A->getTypeHint();
639 bool IsSignedInteger =
642 llvm::Metadata *AttrMDArgs[] = {
643 llvm::ConstantAsMetadata::get(llvm::UndefValue::get(
645 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
646 llvm::IntegerType::get(Context, 32),
647 llvm::APInt(32, (uint64_t)(IsSignedInteger ? 1 : 0))))};
648 Fn->setMetadata(
"vec_type_hint", llvm::MDNode::get(Context, AttrMDArgs));
651 if (
const WorkGroupSizeHintAttr *A = FD->
getAttr<WorkGroupSizeHintAttr>()) {
652 llvm::Metadata *AttrMDArgs[] = {
653 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getXDim())),
654 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getYDim())),
655 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getZDim()))};
656 Fn->setMetadata(
"work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));
659 if (
const ReqdWorkGroupSizeAttr *A = FD->
getAttr<ReqdWorkGroupSizeAttr>()) {
660 llvm::Metadata *AttrMDArgs[] = {
661 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getXDim())),
662 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getYDim())),
663 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getZDim()))};
664 Fn->setMetadata(
"reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs));
667 if (
const OpenCLIntelReqdSubGroupSizeAttr *A =
668 FD->
getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
669 llvm::Metadata *AttrMDArgs[] = {
670 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getSubGroupSize()))};
671 Fn->setMetadata(
"intel_reqd_sub_group_size",
672 llvm::MDNode::get(Context, AttrMDArgs));
678 const Stmt *Body =
nullptr;
679 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(F))
681 else if (
auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(F))
682 Body = OMD->getBody();
684 if (
auto *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
685 auto LastStmt = CS->body_rbegin();
686 if (LastStmt != CS->body_rend())
687 return isa<ReturnStmt>(*LastStmt);
694 Fn->addFnAttr(
"sanitize_thread_no_checking_at_run_time");
695 Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
700bool CodeGenFunction::requiresReturnValueCheck()
const {
701 return requiresReturnValueNullabilityCheck() ||
707 auto *MD = dyn_cast_or_null<CXXMethodDecl>(
D);
708 if (!MD || !MD->getDeclName().getAsIdentifierInfo() ||
709 !MD->getDeclName().getAsIdentifierInfo()->isStr(
"allocate") ||
710 (MD->getNumParams() != 1 && MD->getNumParams() != 2))
713 if (MD->parameters()[0]->getType().getCanonicalType() != Ctx.
getSizeType())
716 if (MD->getNumParams() == 2) {
717 auto *PT = MD->parameters()[1]->getType()->getAs<
PointerType>();
718 if (!PT || !PT->isVoidPointerType() ||
719 !PT->getPointeeType().isConstQualified())
731bool CodeGenFunction::hasInAllocaArg(
const CXXMethodDecl *MD) {
735 return isInAllocaArgument(CGM.getCXXABI(), P->getType());
742 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
755 "Do not use a CodeGenFunction object for more than one function");
759 DidCallStackSave =
false;
768 assert(
CurFn->isDeclaration() &&
"Function already has body?");
773#define SANITIZER(NAME, ID) \
774 if (SanOpts.empty()) \
776 if (SanOpts.has(SanitizerKind::ID)) \
777 if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \
778 SanOpts.set(SanitizerKind::ID, false);
780#include "clang/Basic/Sanitizers.def"
787 bool NoSanitizeCoverage =
false;
790 no_sanitize_mask |=
Attr->getMask();
792 if (
Attr->hasCoverage())
793 NoSanitizeCoverage =
true;
798 if (no_sanitize_mask & SanitizerKind::Address)
799 SanOpts.
set(SanitizerKind::KernelAddress,
false);
800 if (no_sanitize_mask & SanitizerKind::KernelAddress)
802 if (no_sanitize_mask & SanitizerKind::HWAddress)
803 SanOpts.
set(SanitizerKind::KernelHWAddress,
false);
804 if (no_sanitize_mask & SanitizerKind::KernelHWAddress)
808 Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds);
811 Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);
815 if (no_sanitize_mask & SanitizerKind::Thread)
816 Fn->addFnAttr(
"no_sanitize_thread");
821 CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
824 if (
SanOpts.
hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
825 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
827 SanitizerKind::KernelHWAddress))
828 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
830 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
832 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
834 Fn->addFnAttr(llvm::Attribute::SanitizeType);
835 if (
SanOpts.
has(SanitizerKind::NumericalStability))
836 Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
837 if (
SanOpts.
hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
838 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
841 Fn->addFnAttr(llvm::Attribute::SafeStack);
842 if (
SanOpts.
has(SanitizerKind::ShadowCallStack))
843 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
849 Fn->addFnAttr(llvm::Attribute::SanitizeRealtime);
851 Fn->addFnAttr(llvm::Attribute::SanitizeRealtimeBlocking);
855 if (
SanOpts.
hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink))
856 Fn->addFnAttr(llvm::Attribute::OptForFuzzing);
861 if (
const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(
D)) {
862 const IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
865 (OMD->getSelector().isUnarySelector() && II->
isStr(
".cxx_destruct"))) {
874 if (
D &&
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
890 Fn->addFnAttr(
"ptrauth-returns");
892 Fn->addFnAttr(
"ptrauth-calls");
894 Fn->addFnAttr(
"ptrauth-auth-traps");
896 Fn->addFnAttr(
"ptrauth-indirect-gotos");
898 Fn->addFnAttr(
"aarch64-jump-table-hardening");
901 bool AlwaysXRayAttr =
false;
902 if (
const auto *XRayAttr =
D ?
D->
getAttr<XRayInstrumentAttr>() :
nullptr) {
908 Fn->addFnAttr(
"function-instrument",
"xray-always");
909 AlwaysXRayAttr =
true;
911 if (XRayAttr->neverXRayInstrument())
912 Fn->addFnAttr(
"function-instrument",
"xray-never");
913 if (
const auto *LogArgs =
D->
getAttr<XRayLogArgsAttr>())
915 Fn->addFnAttr(
"xray-log-args",
916 llvm::utostr(LogArgs->getArgumentCount()));
921 "xray-instruction-threshold",
927 Fn->addFnAttr(
"xray-ignore-loops");
931 Fn->addFnAttr(
"xray-skip-exit");
935 Fn->addFnAttr(
"xray-skip-entry");
938 if (FuncGroups > 1) {
940 CurFn->getName().bytes_end());
941 auto Group = crc32(FuncName) % FuncGroups;
944 Fn->addFnAttr(
"function-instrument",
"xray-never");
951 Fn->addFnAttr(llvm::Attribute::SkipProfile);
954 Fn->addFnAttr(llvm::Attribute::NoProfile);
961 unsigned Count, Offset;
962 if (
const auto *
Attr =
963 D ?
D->
getAttr<PatchableFunctionEntryAttr>() :
nullptr) {
964 Count =
Attr->getCount();
965 Offset =
Attr->getOffset();
970 if (Count && Offset <= Count) {
971 Fn->addFnAttr(
"patchable-function-entry", std::to_string(Count - Offset));
973 Fn->addFnAttr(
"patchable-function-prefix", std::to_string(Offset));
980 getContext().getTargetInfo().getTriple().isX86() &&
981 getContext().getTargetInfo().getTriple().getEnvironment() !=
982 llvm::Triple::CODE16)
983 Fn->addFnAttr(
"patchable-function",
"prologue-short-redirect");
987 Fn->addFnAttr(
"no-jump-tables",
"true");
991 Fn->addFnAttr(
"no-inline-line-tables");
995 Fn->addFnAttr(
"profile-sample-accurate");
998 Fn->addFnAttr(
"use-sample-profile");
1000 if (
D &&
D->
hasAttr<CFICanonicalJumpTableAttr>())
1001 Fn->addFnAttr(
"cfi-canonical-jump-table");
1003 if (
D &&
D->
hasAttr<NoProfileFunctionAttr>())
1004 Fn->addFnAttr(llvm::Attribute::NoProfile);
1006 if (
D &&
D->
hasAttr<HybridPatchableAttr>())
1007 Fn->addFnAttr(llvm::Attribute::HybridPatchable);
1011 if (
auto *A =
D->
getAttr<FunctionReturnThunksAttr>()) {
1012 switch (A->getThunkType()) {
1013 case FunctionReturnThunksAttr::Kind::Keep:
1015 case FunctionReturnThunksAttr::Kind::Extern:
1016 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
1020 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
1025 getContext().getTargetInfo().getTriple().isSPIRV()) ||
1029 EmitKernelMetadata(FD, Fn);
1032 if (FD && FD->
hasAttr<ClspvLibclcBuiltinAttr>()) {
1033 Fn->setMetadata(
"clspv_libclc_builtin",
1039 if (FD &&
SanOpts.
has(SanitizerKind::Function)) {
1041 llvm::LLVMContext &Ctx =
Fn->getContext();
1042 llvm::MDBuilder MDB(Ctx);
1044 llvm::LLVMContext::MD_func_sanitize,
1045 MDB.createRTTIPointerPrologue(
1052 if (
SanOpts.
has(SanitizerKind::NullabilityReturn)) {
1056 if (!(
SanOpts.
has(SanitizerKind::ReturnsNonnullAttribute) &&
1058 RetValNullabilityPrecondition =
1081 Fn->addFnAttr(llvm::Attribute::NoRecurse);
1084 llvm::fp::ExceptionBehavior FPExceptionBehavior =
1086 Builder.setDefaultConstrainedRounding(RM);
1087 Builder.setDefaultConstrainedExcept(FPExceptionBehavior);
1089 (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
1090 RM != llvm::RoundingMode::NearestTiesToEven))) {
1091 Builder.setIsFPConstrained(
true);
1092 Fn->addFnAttr(llvm::Attribute::StrictFP);
1099 Fn->addFnAttr(
"stackrealign");
1103 Fn->removeFnAttr(
"zero-call-used-regs");
1106 std::optional<std::pair<unsigned, unsigned>> VScaleRange =
1110 CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
1119 llvm::Value *Poison = llvm::PoisonValue::get(
Int32Ty);
1124 Builder.SetInsertPoint(EntryBB);
1128 if (requiresReturnValueCheck()) {
1139 DI->emitFunctionStart(GD,
Loc, StartLoc,
1140 DI->getFunctionType(FD, RetTy, Args),
CurFn,
1146 CurFn->addFnAttr(
"instrument-function-entry",
"__cyg_profile_func_enter");
1148 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1149 "__cyg_profile_func_enter");
1151 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1152 "__cyg_profile_func_enter_bare");
1164 Fn->addFnAttr(
"fentry-call",
"true");
1166 Fn->addFnAttr(
"instrument-function-entry-inlined",
1172 <<
"-mnop-mcount" <<
"-mfentry";
1173 Fn->addFnAttr(
"mnop-mcount");
1179 <<
"-mrecord-mcount" <<
"-mfentry";
1180 Fn->addFnAttr(
"mrecord-mcount");
1186 if (
getContext().getTargetInfo().getTriple().getArch() !=
1187 llvm::Triple::systemz)
1189 <<
"-mpacked-stack";
1190 Fn->addFnAttr(
"packed-stack");
1195 Fn->addFnAttr(
"warn-stack-size",
1208 auto AI =
CurFn->arg_begin();
1224 llvm::Function::arg_iterator EI =
CurFn->arg_end();
1229 cast<llvm::GetElementPtrInst>(Addr)->getResultElementType();
1256 if (FD->
hasAttr<HLSLShaderAttr>()) {
1264 if (
const CXXMethodDecl *MD = dyn_cast_if_present<CXXMethodDecl>(
D);
1285 CXXThisValue = ThisFieldLValue.
getPointer(*
this);
1294 if (FD->hasCapturedVLAType()) {
1297 auto VAT = FD->getCapturedVLAType();
1298 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
1305 CXXThisValue = CXXABIThisValue;
1309 if (CXXABIThisValue) {
1311 SkippedChecks.
set(SanitizerKind::ObjectSize,
true);
1318 SkippedChecks.
set(SanitizerKind::Null,
true);
1322 Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks);
1329 if (!FD || !FD->
hasAttr<NakedAttr>()) {
1330 for (
const VarDecl *VD : Args) {
1335 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
1336 Ty = PVD->getOriginalType();
1346 DI->EmitLocation(
Builder, StartLoc);
1351 LargestVectorWidth = VecWidth->getVectorWidth();
1360 if (
const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
1372 llvm::BasicBlock *SkipCountBB =
nullptr;
1397 if (F->isInterposable())
return;
1399 for (llvm::BasicBlock &BB : *F)
1400 for (llvm::Instruction &I : BB)
1404 F->setDoesNotThrow();
1424 bool PassedParams =
true;
1426 if (
auto Inherited = CD->getInheritedConstructor())
1432 Args.push_back(Param);
1433 if (!Param->hasAttr<PassObjectSizeAttr>())
1437 getContext(), Param->getDeclContext(), Param->getLocation(),
1444 if (MD && (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)))
1452 assert(Fn &&
"generating code for null Function");
1465 std::string FDInlineName = (
Fn->getName() +
".inline").str();
1466 llvm::Module *M =
Fn->getParent();
1467 llvm::Function *Clone = M->getFunction(FDInlineName);
1469 Clone = llvm::Function::Create(
Fn->getFunctionType(),
1470 llvm::GlobalValue::InternalLinkage,
1471 Fn->getAddressSpace(), FDInlineName, M);
1472 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
1474 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
1484 if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) {
1485 std::string FDInlineName = (
Fn->getName() +
".inline").str();
1486 llvm::Module *M =
Fn->getParent();
1487 if (llvm::Function *Clone = M->getFunction(FDInlineName)) {
1488 Clone->replaceAllUsesWith(Fn);
1489 Clone->eraseFromParent();
1497 if (FD->
hasAttr<NoDebugAttr>()) {
1500 Fn->setSubprogram(
nullptr);
1502 DebugInfo =
nullptr;
1512 CurEHLocation = BodyRange.
getEnd();
1524 if (SpecDecl->hasBody(SpecDecl))
1525 Loc = SpecDecl->getLocation();
1531 if (isa<CoroutineBodyStmt>(Body))
1532 ShouldEmitLifetimeMarkers =
true;
1536 if (ShouldEmitLifetimeMarkers)
1544 if (Body && isa_and_nonnull<CoroutineBodyStmt>(Body))
1552 CurFn->addFnAttr(llvm::Attribute::MustProgress);
1556 if (isa<CXXDestructorDecl>(FD))
1558 else if (isa<CXXConstructorDecl>(FD))
1562 FD->
hasAttr<CUDAGlobalAttr>())
1564 else if (isa<CXXMethodDecl>(FD) &&
1565 cast<CXXMethodDecl>(FD)->isLambdaStaticInvoker()) {
1569 }
else if (isa<CXXMethodDecl>(FD) &&
1572 cast<CXXMethodDecl>(FD)->getParent()->getLambdaStaticInvoker() &&
1573 hasInAllocaArg(cast<CXXMethodDecl>(FD))) {
1580 }
else if (FD->
isDefaulted() && isa<CXXMethodDecl>(FD) &&
1581 (cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() ||
1582 cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) {
1589 llvm_unreachable(
"no definition for emitted function");
1599 bool ShouldEmitUnreachable =
1603 SanitizerScope SanScope(
this);
1604 llvm::Value *IsFalse =
Builder.getFalse();
1605 EmitCheck(std::make_pair(IsFalse, SanitizerKind::SO_Return),
1606 SanitizerHandler::MissingReturn,
1608 }
else if (ShouldEmitUnreachable) {
1612 if (
SanOpts.
has(SanitizerKind::Return) || ShouldEmitUnreachable) {
1614 Builder.ClearInsertionPoint();
1625 if (!
CurFn->doesNotThrow())
1634 if (!S)
return false;
1641 if (isa<LabelStmt>(S))
1646 if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
1650 if (isa<SwitchStmt>(S))
1651 IgnoreCaseStmts =
true;
1654 for (
const Stmt *SubStmt : S->children())
1666 if (!S)
return false;
1670 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S) ||
1674 if (isa<BreakStmt>(S))
1678 for (
const Stmt *SubStmt : S->children())
1686 if (!S)
return false;
1692 if (isa<IfStmt>(S) || isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
1693 isa<DoStmt>(S) || isa<ForStmt>(S) || isa<CompoundStmt>(S) ||
1694 isa<CXXForRangeStmt>(S) || isa<CXXTryStmt>(S) ||
1695 isa<ObjCForCollectionStmt>(S) || isa<ObjCAtTryStmt>(S))
1698 if (isa<DeclStmt>(S))
1701 for (
const Stmt *SubStmt : S->children())
1721 llvm::APSInt ResultInt;
1725 ResultBool = ResultInt.getBoolValue();
1733 llvm::APSInt &ResultInt,
1752 while (
const UnaryOperator *Op = dyn_cast<UnaryOperator>(
C->IgnoreParens())) {
1753 if (Op->getOpcode() != UO_LNot)
1755 C = Op->getSubExpr();
1757 return C->IgnoreParens();
1773 llvm::BasicBlock *FalseBlock, uint64_t TrueCount ,
1780 const Stmt *CntrStmt = (CntrIdx ? CntrIdx : Cond);
1782 llvm::BasicBlock *ThenBlock =
nullptr;
1783 llvm::BasicBlock *ElseBlock =
nullptr;
1784 llvm::BasicBlock *NextBlock =
nullptr;
1801 if (LOp == BO_LAnd) {
1802 ThenBlock = CounterIncrBlock;
1803 ElseBlock = FalseBlock;
1804 NextBlock = TrueBlock;
1819 else if (LOp == BO_LOr) {
1820 ThenBlock = TrueBlock;
1821 ElseBlock = CounterIncrBlock;
1822 NextBlock = FalseBlock;
1824 llvm_unreachable(
"Expected Opcode must be that of a Logical Operator");
1848 const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock,
1852 if (
const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
1854 if (CondBOp->getOpcode() == BO_LAnd) {
1859 bool ConstantBool =
false;
1865 FalseBlock, TrueCount, LH);
1876 FalseBlock, TrueCount, LH, CondBOp);
1888 ConditionalEvaluation eval(*
this);
1905 FalseBlock, TrueCount, LH);
1911 if (CondBOp->getOpcode() == BO_LOr) {
1916 bool ConstantBool =
false;
1922 FalseBlock, TrueCount, LH);
1933 FalseBlock, TrueCount, LH, CondBOp);
1945 uint64_t RHSCount = TrueCount - LHSCount;
1947 ConditionalEvaluation eval(*
this);
1972 if (
const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
1980 if (CondUOp->getOpcode() == UO_LNot && !MCDCCondition) {
1998 ConditionalEvaluation cond(*
this);
2011 LHSScaledTrueCount = TrueCount * LHSRatio;
2020 LHSScaledTrueCount, LH, CondOp);
2027 TrueCount - LHSScaledTrueCount, LH, CondOp);
2033 if (
const CXXThrowExpr *Throw = dyn_cast<CXXThrowExpr>(Cond)) {
2053 const Expr *MCDCBaseExpr = Cond;
2060 MCDCBaseExpr = ConditionalOp;
2065 llvm::MDNode *Weights =
nullptr;
2066 llvm::MDNode *Unpredictable =
nullptr;
2073 auto *FD = dyn_cast_or_null<FunctionDecl>(
Call->getCalleeDecl());
2074 if (FD && FD->
getBuiltinID() == Builtin::BI__builtin_unpredictable) {
2076 Unpredictable = MDHelper.createUnpredictable();
2082 llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH);
2083 if (CondV != NewCondV)
2088 Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);
2091 llvm::Instruction *BrInst =
Builder.CreateCondBr(CondV, TrueBlock, FalseBlock,
2092 Weights, Unpredictable);
2094 case HLSLControlFlowHintAttr::Microsoft_branch:
2095 case HLSLControlFlowHintAttr::Microsoft_flatten: {
2098 llvm::ConstantInt *BranchHintConstant =
2100 HLSLControlFlowHintAttr::Spelling::Microsoft_branch
2105 {MDHelper.createString(
"hlsl.controlflow.hint"),
2106 MDHelper.createConstant(BranchHintConstant)});
2107 BrInst->setMetadata(
"hlsl.controlflow.hint",
2112 case HLSLControlFlowHintAttr::SpellingNotCalculated:
2132 llvm::Value *sizeInChars) {
2136 llvm::Value *baseSizeInChars
2142 sizeInChars,
"vla.end");
2144 llvm::BasicBlock *originBB = CGF.
Builder.GetInsertBlock();
2152 llvm::PHINode *cur =
Builder.CreatePHI(begin.
getType(), 2,
"vla.cur");
2167 llvm::Value *done =
Builder.CreateICmpEQ(next, end,
"vla-init.isdone");
2168 Builder.CreateCondBr(done, contBB, loopBB);
2169 cur->addIncoming(next, loopBB);
2179 if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
2190 llvm::Value *SizeVal;
2197 dyn_cast_or_null<VariableArrayType>(
2200 SizeVal = VlaSize.NumElts;
2202 if (!eltSize.
isOne())
2223 llvm::GlobalVariable *NullVariable =
2224 new llvm::GlobalVariable(
CGM.
getModule(), NullConstant->getType(),
2226 llvm::GlobalVariable::PrivateLinkage,
2227 NullConstant, Twine());
2229 NullVariable->setAlignment(NullAlign.
getAsAlign());
2247 if (!IndirectBranch)
2253 IndirectBranch->addDestination(BB);
2254 return llvm::BlockAddress::get(
CurFn, BB);
2259 if (IndirectBranch)
return IndirectBranch->getParent();
2264 llvm::Value *DestVal = TmpBuilder.CreatePHI(
Int8PtrTy, 0,
2265 "indirect.goto.dest");
2268 IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
2269 return IndirectBranch->getParent();
2281 llvm::Value *numVLAElements =
nullptr;
2282 if (isa<VariableArrayType>(
arrayType)) {
2293 baseType = elementType;
2294 return numVLAElements;
2296 }
while (isa<VariableArrayType>(
arrayType));
2308 llvm::ConstantInt *zero =
Builder.getInt32(0);
2309 gepIndices.push_back(zero);
2314 llvm::ArrayType *llvmArrayType =
2316 while (llvmArrayType) {
2317 assert(isa<ConstantArrayType>(
arrayType));
2318 assert(cast<ConstantArrayType>(
arrayType)->getZExtSize() ==
2319 llvmArrayType->getNumElements());
2321 gepIndices.push_back(zero);
2322 countFromCLAs *= llvmArrayType->getNumElements();
2326 dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
2329 "LLVM and Clang types are out-of-synch");
2337 countFromCLAs *= cast<ConstantArrayType>(
arrayType)->getZExtSize();
2348 gepIndices,
"array.begin"),
2354 llvm::Value *numElements
2355 = llvm::ConstantInt::get(
SizeTy, countFromCLAs);
2359 numElements =
Builder.CreateNUWMul(numVLAElements, numElements);
2366 assert(vla &&
"type was not a variable array type!");
2370CodeGenFunction::VlaSizePair
2373 llvm::Value *numElements =
nullptr;
2377 elementType =
type->getElementType();
2378 llvm::Value *vlaSize = VLASizeMap[
type->getSizeExpr()];
2379 assert(vlaSize &&
"no size for VLA!");
2380 assert(vlaSize->getType() ==
SizeTy);
2383 numElements = vlaSize;
2387 numElements =
Builder.CreateNUWMul(numElements, vlaSize);
2389 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
2391 return { numElements, elementType };
2394CodeGenFunction::VlaSizePair
2397 assert(vla &&
"type was not a variable array type!");
2401CodeGenFunction::VlaSizePair
2403 llvm::Value *VlaSize = VLASizeMap[Vla->
getSizeExpr()];
2404 assert(VlaSize &&
"no size for VLA!");
2405 assert(VlaSize->getType() ==
SizeTy);
2410 assert(
type->isVariablyModifiedType() &&
2411 "Must pass variably modified type to EmitVLASizes!");
2418 assert(
type->isVariablyModifiedType());
2420 const Type *ty =
type.getTypePtr();
2423#define TYPE(Class, Base)
2424#define ABSTRACT_TYPE(Class, Base)
2425#define NON_CANONICAL_TYPE(Class, Base)
2426#define DEPENDENT_TYPE(Class, Base) case Type::Class:
2427#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
2428#include "clang/AST/TypeNodes.inc"
2429 llvm_unreachable(
"unexpected dependent type!");
2435 case Type::ExtVector:
2436 case Type::ConstantMatrix:
2440 case Type::TemplateSpecialization:
2441 case Type::ObjCTypeParam:
2442 case Type::ObjCObject:
2443 case Type::ObjCInterface:
2444 case Type::ObjCObjectPointer:
2446 llvm_unreachable(
"type class is never variably-modified!");
2448 case Type::Elaborated:
2449 type = cast<ElaboratedType>(ty)->getNamedType();
2452 case Type::Adjusted:
2453 type = cast<AdjustedType>(ty)->getAdjustedType();
2457 type = cast<DecayedType>(ty)->getPointeeType();
2461 type = cast<PointerType>(ty)->getPointeeType();
2464 case Type::BlockPointer:
2465 type = cast<BlockPointerType>(ty)->getPointeeType();
2468 case Type::LValueReference:
2469 case Type::RValueReference:
2470 type = cast<ReferenceType>(ty)->getPointeeType();
2473 case Type::MemberPointer:
2474 type = cast<MemberPointerType>(ty)->getPointeeType();
2477 case Type::ArrayParameter:
2478 case Type::ConstantArray:
2479 case Type::IncompleteArray:
2481 type = cast<ArrayType>(ty)->getElementType();
2484 case Type::VariableArray: {
2493 llvm::Value *&entry = VLASizeMap[sizeExpr];
2502 SanitizerScope SanScope(
this);
2503 llvm::Value *
Zero = llvm::Constant::getNullValue(size->getType());
2505 llvm::Value *CheckCondition =
2507 ?
Builder.CreateICmpSGT(size, Zero)
2508 :
Builder.CreateICmpUGT(size, Zero);
2509 llvm::Constant *StaticArgs[] = {
2513 std::make_pair(CheckCondition, SanitizerKind::SO_VLABound),
2514 SanitizerHandler::VLABoundNotPositive, StaticArgs, size);
2527 case Type::FunctionProto:
2528 case Type::FunctionNoProto:
2529 type = cast<FunctionType>(ty)->getReturnType();
2534 case Type::UnaryTransform:
2535 case Type::Attributed:
2536 case Type::BTFTagAttributed:
2537 case Type::HLSLAttributedResource:
2538 case Type::SubstTemplateTypeParm:
2539 case Type::MacroQualified:
2540 case Type::CountAttributed:
2546 case Type::Decltype:
2548 case Type::DeducedTemplateSpecialization:
2549 case Type::PackIndexing:
2553 case Type::TypeOfExpr:
2559 type = cast<AtomicType>(ty)->getValueType();
2563 type = cast<PipeType>(ty)->getElementType();
2566 }
while (
type->isVariablyModifiedType());
2570 if (
getContext().getBuiltinVaListType()->isArrayType())
2581 assert(
Init.hasValue() &&
"Invalid DeclRefExpr initializer!");
2584 Dbg->EmitGlobalVariable(
E->getDecl(),
Init);
2587CodeGenFunction::PeepholeProtection
2593 if (!rvalue.
isScalar())
return PeepholeProtection();
2595 if (!isa<llvm::ZExtInst>(value))
return PeepholeProtection();
2599 llvm::Instruction *inst =
new llvm::BitCastInst(value, value->getType(),
"",
2602 PeepholeProtection protection;
2603 protection.Inst = inst;
2608 if (!protection.Inst)
return;
2611 protection.Inst->eraseFromParent();
2617 llvm::Value *Alignment,
2618 llvm::Value *OffsetValue) {
2619 if (Alignment->getType() !=
IntPtrTy)
2622 if (OffsetValue && OffsetValue->getType() !=
IntPtrTy)
2625 llvm::Value *TheCheck =
nullptr;
2627 llvm::Value *PtrIntValue =
2631 bool IsOffsetZero =
false;
2632 if (
const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
2633 IsOffsetZero = CI->isZero();
2636 PtrIntValue =
Builder.CreateSub(PtrIntValue, OffsetValue,
"offsetptr");
2639 llvm::Value *
Zero = llvm::ConstantInt::get(
IntPtrTy, 0);
2642 llvm::Value *MaskedPtr =
Builder.CreateAnd(PtrIntValue, Mask,
"maskedptr");
2643 TheCheck =
Builder.CreateICmpEQ(MaskedPtr, Zero,
"maskcond");
2645 llvm::Instruction *Assumption =
Builder.CreateAlignmentAssumption(
2651 OffsetValue, TheCheck, Assumption);
2657 llvm::Value *Alignment,
2658 llvm::Value *OffsetValue) {
2667 llvm::Value *AnnotatedVal,
2668 StringRef AnnotationStr,
2670 const AnnotateAttr *
Attr) {
2679 return Builder.CreateCall(AnnotationFn, Args);
2683 assert(
D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2686 {V->getType(), CGM.ConstGlobalsPtrTy}),
2692 assert(
D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2694 llvm::Type *VTy =
V->getType();
2695 auto *PTy = dyn_cast<llvm::PointerType>(VTy);
2696 unsigned AS = PTy ? PTy->getAddressSpace() : 0;
2697 llvm::PointerType *IntrinTy =
2706 if (VTy != IntrinTy)
2724 CGF->IsSanitizerScope =
false;
2728 const llvm::Twine &Name,
2729 llvm::BasicBlock::iterator InsertPt)
const {
2732 I->setNoSanitizeMetadata();
2736 llvm::Instruction *I,
const llvm::Twine &Name,
2737 llvm::BasicBlock::iterator InsertPt)
const {
2738 llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, InsertPt);
2740 CGF->InsertHelper(I, Name, InsertPt);
2751 if (BuiltinID == X86::BI__builtin_ia32_cmpps ||
2752 BuiltinID == X86::BI__builtin_ia32_cmpss ||
2753 BuiltinID == X86::BI__builtin_ia32_cmppd ||
2754 BuiltinID == X86::BI__builtin_ia32_cmpsd) {
2756 llvm::StringMap<bool> TargetFetureMap;
2760 if (
Result.getSExtValue() > 7 && !TargetFetureMap.lookup(
"avx"))
2786 std::string MissingFeature;
2787 llvm::StringMap<bool> CallerFeatureMap;
2797 FeatureList, CallerFeatureMap) && !IsHipStdPar) {
2803 TargetDecl->
hasAttr<TargetAttr>()) {
2806 const TargetAttr *TD = TargetDecl->
getAttr<TargetAttr>();
2811 llvm::StringMap<bool> CalleeFeatureMap;
2815 if (F[0] ==
'+' && CalleeFeatureMap.lookup(F.substr(1)))
2816 ReqFeatures.push_back(StringRef(F).substr(1));
2819 for (
const auto &F : CalleeFeatureMap) {
2822 ReqFeatures.push_back(F.getKey());
2824 if (!llvm::all_of(ReqFeatures, [&](StringRef Feature) {
2825 if (!CallerFeatureMap.lookup(Feature)) {
2826 MissingFeature = Feature.str();
2834 llvm::StringMap<bool> CalleeFeatureMap;
2837 for (
const auto &F : CalleeFeatureMap) {
2838 if (F.getValue() && (!CallerFeatureMap.lookup(F.getKey()) ||
2839 !CallerFeatureMap.find(F.getKey())->getValue()) &&
2851 llvm::IRBuilder<> IRB(
Builder.GetInsertBlock(),
Builder.GetInsertPoint());
2852 IRB.SetCurrentDebugLocation(
Builder.getCurrentDebugLocation());
2859 Callee.getAbstractInfo().getCalleeFunctionProtoType();
2865CodeGenFunction::FormAArch64ResolverCondition(
const FMVResolverOption &RO) {
2866 return RO.Features.empty() ? nullptr : EmitAArch64CpuSupports(RO.Features);
2870CodeGenFunction::FormX86ResolverCondition(
const FMVResolverOption &RO) {
2873 if (RO.Architecture) {
2874 StringRef Arch = *RO.Architecture;
2877 if (Arch.starts_with(
"x86-64"))
2883 if (!RO.Features.empty()) {
2884 llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Features);
2892 llvm::Function *Resolver,
2894 llvm::Function *FuncToReturn,
2895 bool SupportsIFunc) {
2896 if (SupportsIFunc) {
2897 Builder.CreateRet(FuncToReturn);
2902 llvm::make_pointer_range(Resolver->args()));
2904 llvm::CallInst *
Result =
Builder.CreateCall(FuncToReturn, Args);
2905 Result->setTailCallKind(llvm::CallInst::TCK_MustTail);
2907 if (Resolver->getReturnType()->isVoidTy())
2916 llvm::Triple::ArchType ArchType =
2920 case llvm::Triple::x86:
2921 case llvm::Triple::x86_64:
2924 case llvm::Triple::aarch64:
2927 case llvm::Triple::riscv32:
2928 case llvm::Triple::riscv64:
2933 assert(
false &&
"Only implemented for x86, AArch64 and RISC-V targets");
2940 if (
getContext().getTargetInfo().getTriple().getOS() !=
2941 llvm::Triple::OSType::Linux) {
2947 Builder.SetInsertPoint(CurBlock);
2951 bool HasDefault =
false;
2952 unsigned DefaultIndex = 0;
2955 for (
unsigned Index = 0; Index < Options.size(); Index++) {
2957 if (Options[Index].Features.empty()) {
2959 DefaultIndex = Index;
2963 Builder.SetInsertPoint(CurBlock);
2989 for (StringRef Feat : Options[Index].Features) {
2990 std::vector<std::string> FeatStr =
2993 assert(FeatStr.size() == 1 &&
"Feature string not delimited");
2995 std::string &CurrFeat = FeatStr.front();
2996 if (CurrFeat[0] ==
'+')
2997 TargetAttrFeats.push_back(CurrFeat.substr(1));
3000 if (TargetAttrFeats.empty())
3003 for (std::string &Feat : TargetAttrFeats)
3004 CurrTargetAttrFeats.push_back(Feat);
3006 Builder.SetInsertPoint(CurBlock);
3009 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
3012 Options[Index].
Function, SupportsIFunc);
3015 Builder.SetInsertPoint(CurBlock);
3016 Builder.CreateCondBr(FeatsCondition, RetBlock, ElseBlock);
3018 CurBlock = ElseBlock;
3023 Builder.SetInsertPoint(CurBlock);
3030 Builder.SetInsertPoint(CurBlock);
3031 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
3032 TrapCall->setDoesNotReturn();
3033 TrapCall->setDoesNotThrow();
3035 Builder.ClearInsertionPoint();
3040 assert(!Options.empty() &&
"No multiversion resolver options found");
3041 assert(Options.back().Features.size() == 0 &&
"Default case must be last");
3043 assert(SupportsIFunc &&
3044 "Multiversion resolver requires target IFUNC support");
3045 bool AArch64CpuInitialized =
false;
3048 for (
const FMVResolverOption &RO : Options) {
3049 Builder.SetInsertPoint(CurBlock);
3050 llvm::Value *
Condition = FormAArch64ResolverCondition(RO);
3059 if (!AArch64CpuInitialized) {
3060 Builder.SetInsertPoint(CurBlock, CurBlock->begin());
3061 EmitAArch64CpuInit();
3062 AArch64CpuInitialized =
true;
3063 Builder.SetInsertPoint(CurBlock);
3066 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
3075 Builder.SetInsertPoint(CurBlock);
3076 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
3077 TrapCall->setDoesNotReturn();
3078 TrapCall->setDoesNotThrow();
3080 Builder.ClearInsertionPoint();
3090 Builder.SetInsertPoint(CurBlock);
3093 for (
const FMVResolverOption &RO : Options) {
3094 Builder.SetInsertPoint(CurBlock);
3095 llvm::Value *
Condition = FormX86ResolverCondition(RO);
3099 assert(&RO == Options.end() - 1 &&
3100 "Default or Generic case must be last");
3106 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
3115 Builder.SetInsertPoint(CurBlock);
3116 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
3117 TrapCall->setDoesNotReturn();
3118 TrapCall->setDoesNotThrow();
3120 Builder.ClearInsertionPoint();
3132 llvm::Value *OffsetValue, llvm::Value *TheCheck,
3133 llvm::Instruction *Assumption) {
3134 assert(isa_and_nonnull<llvm::CallInst>(Assumption) &&
3135 cast<llvm::CallInst>(Assumption)->getCalledOperand() ==
3136 llvm::Intrinsic::getOrInsertDeclaration(
3137 Builder.GetInsertBlock()->getParent()->getParent(),
3138 llvm::Intrinsic::assume) &&
3139 "Assumption should be a call to llvm.assume().");
3140 assert(&(
Builder.GetInsertBlock()->back()) == Assumption &&
3141 "Assumption should be the last instruction of the basic block, "
3142 "since the basic block is still being generated.");
3154 Assumption->removeFromParent();
3157 SanitizerScope SanScope(
this);
3160 OffsetValue =
Builder.getInt1(
false);
3168 EmitCheck({std::make_pair(TheCheck, SanitizerKind::SO_Alignment)},
3169 SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
3180 return DI->SourceLocToDebugLoc(Location);
3182 return llvm::DebugLoc();
3186CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
3197 llvm::Type *CondTy = Cond->getType();
3198 assert(CondTy->isIntegerTy(1) &&
"expecting condition to be a boolean");
3199 llvm::Function *FnExpect =
3201 llvm::Value *ExpectedValueOfCond =
3203 return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond},
3204 Cond->getName() +
".expval");
3206 llvm_unreachable(
"Unknown Likelihood");
3210 unsigned NumElementsDst,
3211 const llvm::Twine &Name) {
3212 auto *SrcTy = cast<llvm::FixedVectorType>(SrcVec->getType());
3213 unsigned NumElementsSrc = SrcTy->getNumElements();
3214 if (NumElementsSrc == NumElementsDst)
3217 std::vector<int> ShuffleMask(NumElementsDst, -1);
3218 for (
unsigned MaskIdx = 0;
3219 MaskIdx < std::min<>(NumElementsDst, NumElementsSrc); ++MaskIdx)
3220 ShuffleMask[MaskIdx] = MaskIdx;
3222 return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name);
3237 llvm::Value *Args[] = {Key, Discriminator};
3238 Bundles.emplace_back(
"ptrauth", Args);
3244 unsigned IntrinsicID) {
3251 if (!Discriminator) {
3256 auto OrigType =
Pointer->getType();
3274 llvm::Intrinsic::ptrauth_sign);
3280 auto StripIntrinsic = CGF.
CGM.
getIntrinsic(llvm::Intrinsic::ptrauth_strip);
3284 auto OrigType =
Pointer->getType();
3301 llvm::Intrinsic::ptrauth_auth);
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 llvm::Value * EmitPointerAuthCommon(CodeGenFunction &CGF, const CGPointerAuthInfo &PointerAuth, llvm::Value *Pointer, unsigned IntrinsicID)
static void CreateMultiVersionResolverReturn(CodeGenModule &CGM, llvm::Function *Resolver, CGBuilderTy &Builder, llvm::Function *FuncToReturn, bool SupportsIFunc)
static llvm::Value * EmitStrip(CodeGenFunction &CGF, const CGPointerAuthInfo &PointerAuth, llvm::Value *Pointer)
static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, Address dest, Address src, llvm::Value *sizeInChars)
emitNonZeroVLAInit - Emit the "zero" initialization of a variable-length array whose elements have a ...
static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB)
static LValue makeNaturalAlignAddrLValue(llvm::Value *V, QualType T, bool ForPointeeType, bool MightBeSigned, CodeGenFunction &CGF, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
static void TryMarkNoThrow(llvm::Function *F)
Tries to mark the given function nounwind based on the non-existence of any throwing calls within it.
static llvm::Constant * getPrologueSignature(CodeGenModule &CGM, const FunctionDecl *FD)
Return the UBSan prologue signature for FD if one is available.
static bool endsWithReturn(const Decl *F)
Determine whether the function F ends with a return stmt.
static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, const LangOptions &LangOpts)
shouldEmitLifetimeMarkers - Decide whether we need emit the life-time markers.
static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
llvm::MachO::Target Target
Defines the Objective-C statement AST node classes.
Enumerates target-specific builtins in their own namespaces within namespace clang.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const
Parses the target attributes passed in, and returns only the ones that are valid feature names.
Builtin::Context & BuiltinInfo
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
bool hasAnyFunctionEffects() const
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
const TargetInfo & getTargetInfo() const
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Attr - This represents one attribute.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
const char * getRequiredFeatures(unsigned ID) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isLambda() const
Determine whether this class describes a lambda function object.
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
bool isCapturelessLambda() const
A C++ throw-expression (C++ [except.throw]).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
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.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
bool isOne() const
isOne - Test whether the quantity equals one.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string SampleProfileFile
Name of the profile file to use with -fprofile-sample-use.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
XRayInstrSet XRayInstrumentationBundle
Set of XRay instrumentation kinds to emit.
bool hasSanitizeCoverage() const
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
bool hasSanitizeBinaryMetadata() const
unsigned getInAllocaFieldIndex() const
bool getIndirectByVal() const
@ InAlloca
InAlloca - Pass the argument directly using the LLVM inalloca attribute.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
bool isSRetAfterThis() const
CharUnits getIndirectAlign() const
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::PointerType * getType() const
Return the type of the pointer value.
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
This is an IRBuilder insertion helper that forwards to CodeGenFunction::InsertHelper,...
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const override
This forwards to CodeGenFunction::InsertHelper.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
llvm::ConstantInt * getSize(CharUnits N)
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args)=0
Emits a kernel launch stub.
Implements C++ ABI-specific code generation functions.
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
virtual bool HasThisReturn(GlobalDecl GD) const
Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params)
Build a parameter variable suitable for 'this'.
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
MangleContext & getMangleContext()
Gets the mangle context.
All available information about a concrete callee.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
bool isReturnsRetained() const
In ARC, whether this function retains its return value.
CanQualType getReturnType() const
bool isDelegateCall() const
unsigned getMaxVectorWidth() const
Return the maximum vector width in the arguments.
llvm::StructType * getArgStruct() const
Get the struct type used to represent all the arguments in memory.
void setHLSLFunctionAttributes(const FunctionDecl *FD, llvm::Function *Fn)
void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn)
virtual void functionFinished(CodeGenFunction &CGF)
Cleans up references to the objects in finished function.
llvm::OpenMPIRBuilder & getOMPBuilder()
virtual void emitFunctionProlog(CodeGenFunction &CGF, const Decl *D)
Emits OpenMP-specific function prolog.
llvm::Value * getDiscriminator() const
virtual ~CGCapturedStmtInfo()
CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures)
SanitizerScope(CodeGenFunction *CGF)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
void EmitDestructorBody(FunctionArgList &Args)
void EmitBranchToCounterBlock(const Expr *Cond, BinaryOperator::Opcode LOp, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount=0, Stmt::Likelihood LH=Stmt::LH_None, const Expr *CntrIdx=nullptr)
EmitBranchToCounterBlock - Emit a conditional branch to a new block that increments a profile counter...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
void EmitPointerAuthOperandBundle(const CGPointerAuthInfo &Info, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitAArch64MultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
void unprotectFromPeepholes(PeepholeProtection protection)
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)
bool ShouldInstrumentFunction()
ShouldInstrumentFunction - Return true if the current function should be instrumented with __cyg_prof...
Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
static bool hasScalarEvaluationKind(QualType T)
void EmitMultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
FieldDecl * LambdaThisCaptureField
LValue MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T)
Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known to be unsigned.
void EmitKCFIOperandBundle(const CGCallee &Callee, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue, llvm::Value *TheCheck, llvm::Instruction *Assumption)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
void EmitEndEHSpec(const Decl *D)
EmitEndEHSpec - Emit the end of the exception spec.
llvm::Value * EmitRISCVCpuSupports(const CallExpr *E)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack
Stack to track the controlled convergence tokens.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc)
EmitFunctionEpilog - Emit the target specific LLVM code to return the given temporary.
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
llvm::BasicBlock * EHResumeBlock
EHResumeBlock - Unified block containing a call to llvm.eh.resume.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
void EmitFunctionBody(const Stmt *Body)
void EmitRISCVMultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
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.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
@ TCK_ConstructorCall
Checking the 'this' pointer for a constructor call.
@ TCK_MemberCall
Checking the 'this' pointer for a call to a non-static member function.
void setCurrentProfileCount(uint64_t Count)
Set the profiler's current count.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, std::initializer_list< llvm::Value ** > ValuesToReload={})
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
llvm::Type * ConvertTypeForMem(QualType T)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
bool AlwaysEmitXRayCustomEvents() const
AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit XRay custom event handling c...
JumpDest ReturnBlock
ReturnBlock - Unified return block.
void EmitVarAnnotations(const VarDecl *D, llvm::Value *V)
Emit local annotations for the local variable V, declared by D.
llvm::Value * EmitPointerAuthSign(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
static const Expr * stripCond(const Expr *C)
Ignore parentheses and logical-NOT to track conditions consistently.
PeepholeProtection protectFromPeepholes(RValue rvalue)
protectFromPeepholes - Protect a value that we're intending to store to the side, but which will prob...
const TargetInfo & getTarget() const
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)
Converts Location to a DebugLoc, if debug information is enabled.
void EmitFunctionProlog(const CGFunctionInfo &FI, llvm::Function *Fn, const FunctionArgList &Args)
EmitFunctionProlog - Emit the target specific LLVM code to load the arguments for the given function.
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...
void EmitX86MultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
llvm::Value * EmitRISCVCpuInit()
void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
bool ShouldSkipSanitizerInstrumentation()
ShouldSkipSanitizerInstrumentation - Return true if the current function should not be instrumented w...
uint64_t getCurrentProfileCount()
Get the profiler's current count.
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
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.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn)
Annotate the function with an attribute that disables TSan checking at runtime.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
CGDebugInfo * getDebugInfo()
Address EmitVAListRef(const Expr *E)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
void maybeCreateMCDCCondBitmap()
Allocate a temp value on the stack that MCDC can use to track condition results.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
bool ShouldXRayInstrumentFunction() const
ShouldXRayInstrument - Return true if the current function should be instrumented with XRay nop sleds...
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
llvm::Value * EmitCheckValue(llvm::Value *V)
Convert a value into a format suitable for passing to a runtime sanitizer handler.
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
bool AlwaysEmitXRayTypedEvents() const
AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit XRay typed event handling ...
void EmitConstructorBody(FunctionArgList &Args)
void SetFastMathFlags(FPOptions FPFeatures)
Set the codegen fast-math flags.
ASTContext & getContext() const
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl)
void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD)
llvm::SmallVector< char, 256 > LifetimeExtendedCleanupStack
void EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
Address ReturnValuePointer
ReturnValuePointer - The temporary alloca to hold a pointer to sret.
llvm::ConstantInt * getUBSanFunctionTypeHash(QualType T) const
Return a type hash constant for a function instrumented by -fsanitize=function.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
JumpDest getJumpDestForLabel(const LabelDecl *S)
getBasicBlockForLabel - Return the LLVM basicblock that the specified label maps to.
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Type * ConvertType(QualType T)
CodeGenTypes & getTypes() const
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
HLSLControlFlowHintAttr::Spelling HLSLControlFlowAttr
HLSL Branch attribute.
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
llvm::SmallVector< const ParmVarDecl *, 4 > FnArgs
Save Parameter Decl for coroutine.
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
RawAddress NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
Address EmitMSVAListRef(const Expr *E)
Emit a "reference" to a __builtin_ms_va_list; this is always the value of the expression,...
VarBypassDetector Bypasses
EHScopeStack::stable_iterator PrologueCleanupDepth
PrologueCleanupDepth - The cleanup depth enclosing all the cleanups associated with the parameters.
static bool mightAddDeclToScope(const Stmt *S)
Determine if the given statement might introduce a declaration into the current scope,...
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
const CGFunctionInfo * CurFnInfo
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const
CGBuilder insert helper.
Address EmitFieldAnnotations(const FieldDecl *D, Address V)
Emit field annotations for the given field & value.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
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 ...
llvm::LLVMContext & getLLVMContext()
bool SawAsmBlock
Whether we processed a Microsoft-style asm block during CodeGen.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
bool checkIfFunctionMustProgress()
Returns true if a function must make progress, which means the mustprogress attribute can be added.
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitAnnotationCall(llvm::Function *AnnotationFn, llvm::Value *AnnotatedVal, StringRef AnnotationStr, SourceLocation Location, const AnnotateAttr *Attr)
Emit an annotation call (intrinsic).
llvm::BasicBlock * GetIndirectGotoBlock()
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
llvm::DebugLoc EmitReturnBlock()
Emit the unified return block, trying to avoid its emission when possible.
void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo)
LValue EmitLValueForLambdaField(const FieldDecl *Field)
static bool containsBreak(const Stmt *S)
containsBreak - Return true if the statement contains a break out of it.
This class organizes the cross-function state that is used while generating LLVM code.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::Constant * EmitAnnotationArgs(const AnnotateAttr *Attr)
Emit additional args of the annotation.
llvm::Module & getModule() const
DiagnosticsEngine & getDiags() const
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
CGCUDARuntime & getCUDARuntime()
Return a reference to the configured CUDA runtime.
llvm::Constant * EmitAnnotationLineNo(SourceLocation L)
Emit the annotation line number.
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
const llvm::DataLayout & getDataLayout() const
bool shouldEmitConvergenceTokens() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, StringRef Category=StringRef()) const
Imbue XRay attributes to a function, applying the always/never attribute lists in the process.
ProfileList::ExclusionType isFunctionBlockedFromProfileInstr(llvm::Function *Fn, SourceLocation Loc) const
ASTContext & getContext() const
llvm::SanitizerStatReport & getSanStats()
llvm::Constant * EmitAnnotationString(StringRef Str)
Emit an annotation string.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
void GenKernelArgMetadata(llvm::Function *FN, const FunctionDecl *FD=nullptr, CodeGenFunction *CGF=nullptr)
OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument information in the program executab...
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
llvm::ConstantInt * CreateKCFITypeId(QualType T)
Generate a KCFI type identifier for T.
bool MayDropFunctionReturn(const ASTContext &Context, QualType ReturnType) const
Whether this function's return type has no side effects, and thus may be trivially discarded if it is...
llvm::Constant * EmitAnnotationUnit(SourceLocation Loc)
Emit the annotation's translation unit.
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
void verifyCounterMap() const
void markStmtMaybeUsed(const Stmt *S)
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
bool inheritingCtorHasParams(const InheritedConstructor &Inherited, CXXCtorType Type)
Determine if a C++ inheriting constructor should have parameters matching those of its inherited cons...
llvm::Type * convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy=nullptr)
Given that T is a scalar type, return the IR type that should be used for load and store operations.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
bool empty() const
Determines whether the exception-scopes stack is empty.
bool containsOnlyNoopCleanups(stable_iterator Old) const
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
llvm::Value * getPointer(CodeGenFunction &CGF) const
Address getAddress() const
void InsertHelper(llvm::Instruction *I) const
Function called by the CodeGenFunction when an instruction is created.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
llvm::Value * getPointer() const
virtual void checkFunctionABI(CodeGenModule &CGM, const FunctionDecl *Decl) const
Any further codegen related checks that need to be done on a function signature in a target specific ...
virtual llvm::Constant * getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const
Return a constant used by UBSan as a signature to identify functions possessing type information,...
void Init(const Stmt *Body)
Clear the object and pre-process for the given statement, usually function body statement.
CompoundStmt - This represents a group of statements like { stmt stmt }.
ConditionalOperator - The ?: ternary operator.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
Decl * getNonClosureContext()
Find the innermost non-closure ancestor of this declaration, walking up through blocks,...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
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...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
ExtVectorType - Extended vector type.
LangOptions::FPExceptionModeKind getExceptionMode() const
bool allowFPContractAcrossStatement() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
Represents a function declaration or definition.
bool isMultiVersion() const
True if this function is considered a multiversioned function.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
bool UsesFPIntrin() const
Determine whether the function was declared in source context that requires constrained FP intrinsics...
bool usesSEHTry() const
Indicates the function uses __try.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
FunctionEffectsRef getFunctionEffects() const
bool isMSVCRTEntryPoint() const
Determines whether this function is a MSVCRT user defined entry point.
bool isInlineBuiltinDeclaration() const
Determine if this function provides an inline implementation of a builtin.
bool hasImplicitReturnZero() const
Whether falling off this function implicitly returns null/zero.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program.
bool isDefaulted() const
Whether this function is defaulted.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
Represents a prototype with parameter type info, e.g.
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Represents the declaration of a label.
FPExceptionModeKind
Possible floating point exception behavior.
@ FPE_Strict
Strictly preserve the floating-point exception semantics.
@ FPE_MayTrap
Transformations do not cause new exceptions but may hide some.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
SanitizerSet Sanitize
Set of enabled sanitizers.
RoundingMode getDefaultRoundingMode() const
virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a parameter to a function.
ParsedAttr - Represents a syntactic attribute.
PointerType - C99 6.7.5.1 - Pointer Declarators.
@ Forbid
Profiling is forbidden using the noprofile attribute.
@ Skip
Profiling is skipped using the skipprofile attribute.
@ Allow
Profiling is allowed.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Likelihood
The likelihood of a branch being taken.
@ LH_Unlikely
Branch has the [[unlikely]] attribute.
@ LH_None
No attribute set or branches of the IfStmt have the same attribute.
@ LH_Likely
Branch has the [[likely]] attribute.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts, bool IsArmStreamingFunction) const
Returns target-specific min and max values VScale_Range.
bool supportsIFunc() const
Identify whether this target supports IFuncs.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isPointerType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isFunctionNoProtoType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a variable declaration or definition.
Represents a C array with a specified size that is not an integer-constant-expression.
Expr * getSizeExpr() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)
Returns true if the required target features of a builtin function are enabled.
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
constexpr XRayInstrMask Typed
constexpr XRayInstrMask FunctionExit
constexpr XRayInstrMask FunctionEntry
constexpr XRayInstrMask Custom
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ NonNull
Values of this type can never be null.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
const FunctionProtoType * T
llvm::fp::ExceptionBehavior ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind)
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
@ Other
Other implicit parameter.
@ EST_None
no exception specification
@ Implicit
An implicit conversion.
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::BasicBlock * getBlock() const
This structure provides a set of types that are commonly used during IR emission.
llvm::PointerType * ConstGlobalsPtrTy
void* in the address space for constant globals
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
EvalResult is a struct with detailed info about an evaluated expression.
A FunctionEffect plus a potential boolean expression determining whether the effect is declared (e....
Contains information gathered from parsing the contents of TargetAttr.
std::vector< std::string > Features
bool ReturnAddresses
Should return addresses be authenticated?
bool AArch64JumpTableHardening
Use hardened lowering for jump-table dispatch?
PointerAuthSchema FunctionPointers
The ABI for C function pointers.
bool AuthTraps
Do authentication failures cause a trap?
bool IndirectGotos
Do indirect goto label addresses need to be authenticated?
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.
SanitizerMask Mask
Bitmask of enabled sanitizers.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
bool has(XRayInstrMask K) const