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/IntrinsicInst.h"
44#include "llvm/IR/Intrinsics.h"
45#include "llvm/IR/MDBuilder.h"
46#include "llvm/IR/Operator.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() {
109llvm::fp::ExceptionBehavior
117 llvm_unreachable(
"Unsupported FP Exception Behavior");
122 llvm::FastMathFlags FMF;
123 FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
124 FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
125 FMF.setNoInfs(FPFeatures.getNoHonorInfs());
126 FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
127 FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
128 FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
142 ConstructorHelper(FPFeatures);
145void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(
FPOptions FPFeatures) {
146 OldFPFeatures = CGF.CurFPFeatures;
147 CGF.CurFPFeatures = FPFeatures;
149 OldExcept = CGF.Builder.getDefaultConstrainedExcept();
150 OldRounding = CGF.Builder.getDefaultConstrainedRounding();
152 if (OldFPFeatures == FPFeatures)
155 FMFGuard.emplace(CGF.Builder);
158 CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
159 auto NewExceptionBehavior =
162 CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
164 CGF.SetFastMathFlags(FPFeatures);
166 assert((CGF.CurFuncDecl ==
nullptr || CGF.Builder.getIsFPConstrained() ||
167 isa<CXXConstructorDecl>(CGF.CurFuncDecl) ||
168 isa<CXXDestructorDecl>(CGF.CurFuncDecl) ||
169 (NewExceptionBehavior == llvm::fp::ebIgnore &&
170 NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
171 "FPConstrained should be enabled on entire function");
173 auto mergeFnAttrValue = [&](StringRef Name,
bool Value) {
175 CGF.CurFn->getFnAttribute(Name).getValueAsBool();
176 auto NewValue = OldValue &
Value;
177 if (OldValue != NewValue)
178 CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));
180 mergeFnAttrValue(
"no-infs-fp-math", FPFeatures.getNoHonorInfs());
181 mergeFnAttrValue(
"no-nans-fp-math", FPFeatures.getNoHonorNaNs());
182 mergeFnAttrValue(
"no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
185 FPFeatures.getAllowFPReassociate() && FPFeatures.getAllowReciprocal() &&
186 FPFeatures.getAllowApproxFunc() && FPFeatures.getNoSignedZero() &&
191 CGF.CurFPFeatures = OldFPFeatures;
192 CGF.Builder.setDefaultConstrainedExcept(OldExcept);
193 CGF.Builder.setDefaultConstrainedRounding(OldRounding);
228 switch (
type->getTypeClass()) {
229#define TYPE(name, parent)
230#define ABSTRACT_TYPE(name, parent)
231#define NON_CANONICAL_TYPE(name, parent) case Type::name:
232#define DEPENDENT_TYPE(name, parent) case Type::name:
233#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
234#include "clang/AST/TypeNodes.inc"
235 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
238 case Type::DeducedTemplateSpecialization:
239 llvm_unreachable(
"undeduced type in IR-generation");
244 case Type::BlockPointer:
245 case Type::LValueReference:
246 case Type::RValueReference:
247 case Type::MemberPointer:
249 case Type::ExtVector:
250 case Type::ConstantMatrix:
251 case Type::FunctionProto:
252 case Type::FunctionNoProto:
254 case Type::ObjCObjectPointer:
264 case Type::ConstantArray:
265 case Type::IncompleteArray:
266 case Type::VariableArray:
268 case Type::ObjCObject:
269 case Type::ObjCInterface:
274 type = cast<AtomicType>(
type)->getValueType();
277 llvm_unreachable(
"unknown type kind!");
284 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
287 assert(!CurBB->getTerminator() &&
"Unexpected terminated block.");
297 return llvm::DebugLoc();
304 llvm::BranchInst *BI =
306 if (BI && BI->isUnconditional() &&
310 llvm::DebugLoc Loc = BI->getDebugLoc();
311 Builder.SetInsertPoint(BI->getParent());
312 BI->eraseFromParent();
324 return llvm::DebugLoc();
329 if (!BB->use_empty()) {
337 assert(BreakContinueStack.empty() &&
338 "mismatched push/pop in break/continue stack!");
340 bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
341 && NumSimpleReturnExprs == NumReturnExprs
356 if (OnlySimpleReturnStmts)
357 DI->EmitLocation(
Builder, LastStopPoint);
359 DI->EmitLocation(
Builder, EndLoc);
367 bool HasOnlyLifetimeMarkers =
369 bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;
371 std::optional<ApplyDebugLocation> OAL;
376 if (OnlySimpleReturnStmts)
377 DI->EmitLocation(
Builder, EndLoc);
392 CurFn->addFnAttr(
"instrument-function-exit",
"__cyg_profile_func_exit");
394 CurFn->addFnAttr(
"instrument-function-exit-inlined",
395 "__cyg_profile_func_exit");
409 "did not remove all scopes from cleanup stack!");
413 if (IndirectBranch) {
420 if (!EscapedLocals.empty()) {
424 EscapeArgs.resize(EscapedLocals.size());
425 for (
auto &Pair : EscapedLocals)
426 EscapeArgs[Pair.second] = Pair.first;
427 llvm::Function *FrameEscapeFn = llvm::Intrinsic::getDeclaration(
435 Ptr->eraseFromParent();
439 if (PostAllocaInsertPt) {
440 llvm::Instruction *PostPtr = PostAllocaInsertPt;
441 PostAllocaInsertPt =
nullptr;
442 PostPtr->eraseFromParent();
447 if (IndirectBranch) {
448 llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
449 if (PN->getNumIncomingValues() == 0) {
450 PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
451 PN->eraseFromParent();
460 for (
const auto &FuncletAndParent : TerminateFunclets)
466 for (
const auto &R : DeferredReplacements) {
467 if (llvm::Value *Old = R.first) {
468 Old->replaceAllUsesWith(R.second);
469 cast<llvm::Instruction>(Old)->eraseFromParent();
472 DeferredReplacements.clear();
481 llvm::DominatorTree DT(*
CurFn);
482 llvm::PromoteMemToReg(
488 for (llvm::Argument &A :
CurFn->args())
489 if (
auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
491 std::max((uint64_t)LargestVectorWidth,
492 VT->getPrimitiveSizeInBits().getKnownMinValue());
495 if (
auto *VT = dyn_cast<llvm::VectorType>(
CurFn->getReturnType()))
497 std::max((uint64_t)LargestVectorWidth,
498 VT->getPrimitiveSizeInBits().getKnownMinValue());
510 if (
getContext().getTargetInfo().getTriple().isX86())
511 CurFn->addFnAttr(
"min-legal-vector-width",
512 llvm::utostr(LargestVectorWidth));
515 std::optional<std::pair<unsigned, unsigned>> VScaleRange =
518 CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
529 if (RetAlloca && RetAlloca->use_empty()) {
530 RetAlloca->eraseFromParent();
583 llvm::raw_string_ostream Out(Mangled);
585 return llvm::ConstantInt::get(
586 CGM.
Int32Ty,
static_cast<uint32_t
>(llvm::xxh3_64bits(Mangled)));
589void CodeGenFunction::EmitKernelMetadata(
const FunctionDecl *FD,
590 llvm::Function *Fn) {
591 if (!FD->
hasAttr<OpenCLKernelAttr>() && !FD->
hasAttr<CUDAGlobalAttr>())
601 if (
const VecTypeHintAttr *A = FD->
getAttr<VecTypeHintAttr>()) {
602 QualType HintQTy = A->getTypeHint();
604 bool IsSignedInteger =
607 llvm::Metadata *AttrMDArgs[] = {
608 llvm::ConstantAsMetadata::get(llvm::UndefValue::get(
610 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
611 llvm::IntegerType::get(Context, 32),
612 llvm::APInt(32, (uint64_t)(IsSignedInteger ? 1 : 0))))};
613 Fn->setMetadata(
"vec_type_hint", llvm::MDNode::get(Context, AttrMDArgs));
616 if (
const WorkGroupSizeHintAttr *A = FD->
getAttr<WorkGroupSizeHintAttr>()) {
617 llvm::Metadata *AttrMDArgs[] = {
618 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getXDim())),
619 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getYDim())),
620 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getZDim()))};
621 Fn->setMetadata(
"work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));
624 if (
const ReqdWorkGroupSizeAttr *A = FD->
getAttr<ReqdWorkGroupSizeAttr>()) {
625 llvm::Metadata *AttrMDArgs[] = {
626 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getXDim())),
627 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getYDim())),
628 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getZDim()))};
629 Fn->setMetadata(
"reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs));
632 if (
const OpenCLIntelReqdSubGroupSizeAttr *A =
633 FD->
getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
634 llvm::Metadata *AttrMDArgs[] = {
635 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getSubGroupSize()))};
636 Fn->setMetadata(
"intel_reqd_sub_group_size",
637 llvm::MDNode::get(Context, AttrMDArgs));
643 const Stmt *Body =
nullptr;
644 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(F))
646 else if (
auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(F))
647 Body = OMD->getBody();
649 if (
auto *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
650 auto LastStmt = CS->body_rbegin();
651 if (LastStmt != CS->body_rend())
652 return isa<ReturnStmt>(*LastStmt);
659 Fn->addFnAttr(
"sanitize_thread_no_checking_at_run_time");
660 Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
665bool CodeGenFunction::requiresReturnValueCheck()
const {
666 return requiresReturnValueNullabilityCheck() ||
672 auto *MD = dyn_cast_or_null<CXXMethodDecl>(D);
673 if (!MD || !MD->getDeclName().getAsIdentifierInfo() ||
674 !MD->getDeclName().getAsIdentifierInfo()->isStr(
"allocate") ||
675 (MD->getNumParams() != 1 && MD->getNumParams() != 2))
678 if (MD->parameters()[0]->getType().getCanonicalType() != Ctx.
getSizeType())
681 if (MD->getNumParams() == 2) {
682 auto *PT = MD->parameters()[1]->getType()->getAs<
PointerType>();
683 if (!PT || !PT->isVoidPointerType() ||
684 !PT->getPointeeType().isConstQualified())
696bool CodeGenFunction::hasInAllocaArg(
const CXXMethodDecl *MD) {
700 return isInAllocaArgument(CGM.getCXXABI(), P->getType());
707 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
720 "Do not use a CodeGenFunction object for more than one function");
724 DidCallStackSave =
false;
726 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
733 assert(
CurFn->isDeclaration() &&
"Function already has body?");
738#define SANITIZER(NAME, ID) \
739 if (SanOpts.empty()) \
741 if (SanOpts.has(SanitizerKind::ID)) \
742 if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \
743 SanOpts.set(SanitizerKind::ID, false);
745#include "clang/Basic/Sanitizers.def"
752 bool NoSanitizeCoverage =
false;
755 no_sanitize_mask |=
Attr->getMask();
757 if (
Attr->hasCoverage())
758 NoSanitizeCoverage =
true;
763 if (no_sanitize_mask & SanitizerKind::Address)
764 SanOpts.
set(SanitizerKind::KernelAddress,
false);
765 if (no_sanitize_mask & SanitizerKind::KernelAddress)
767 if (no_sanitize_mask & SanitizerKind::HWAddress)
768 SanOpts.
set(SanitizerKind::KernelHWAddress,
false);
769 if (no_sanitize_mask & SanitizerKind::KernelHWAddress)
773 Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds);
776 Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);
780 if (no_sanitize_mask & SanitizerKind::Thread)
781 Fn->addFnAttr(
"no_sanitize_thread");
786 CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
789 if (
SanOpts.
hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
790 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
792 SanitizerKind::KernelHWAddress))
793 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
795 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
797 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
798 if (
SanOpts.
hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
799 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
802 Fn->addFnAttr(llvm::Attribute::SafeStack);
803 if (
SanOpts.
has(SanitizerKind::ShadowCallStack))
804 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
807 if (
SanOpts.
hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink))
808 Fn->addFnAttr(llvm::Attribute::OptForFuzzing);
813 if (
const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
814 IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
817 (OMD->getSelector().isUnarySelector() && II->
isStr(
".cxx_destruct"))) {
826 if (D &&
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
840 bool AlwaysXRayAttr =
false;
841 if (
const auto *XRayAttr = D ? D->
getAttr<XRayInstrumentAttr>() :
nullptr) {
847 Fn->addFnAttr(
"function-instrument",
"xray-always");
848 AlwaysXRayAttr =
true;
850 if (XRayAttr->neverXRayInstrument())
851 Fn->addFnAttr(
"function-instrument",
"xray-never");
852 if (
const auto *LogArgs = D->
getAttr<XRayLogArgsAttr>())
854 Fn->addFnAttr(
"xray-log-args",
855 llvm::utostr(LogArgs->getArgumentCount()));
860 "xray-instruction-threshold",
866 Fn->addFnAttr(
"xray-ignore-loops");
870 Fn->addFnAttr(
"xray-skip-exit");
874 Fn->addFnAttr(
"xray-skip-entry");
877 if (FuncGroups > 1) {
879 CurFn->getName().bytes_end());
880 auto Group = crc32(FuncName) % FuncGroups;
883 Fn->addFnAttr(
"function-instrument",
"xray-never");
890 Fn->addFnAttr(llvm::Attribute::SkipProfile);
893 Fn->addFnAttr(llvm::Attribute::NoProfile);
900 unsigned Count, Offset;
901 if (
const auto *
Attr =
902 D ? D->
getAttr<PatchableFunctionEntryAttr>() :
nullptr) {
903 Count =
Attr->getCount();
904 Offset =
Attr->getOffset();
909 if (Count && Offset <= Count) {
910 Fn->addFnAttr(
"patchable-function-entry", std::to_string(Count - Offset));
912 Fn->addFnAttr(
"patchable-function-prefix", std::to_string(Offset));
919 getContext().getTargetInfo().getTriple().isX86() &&
920 getContext().getTargetInfo().getTriple().getEnvironment() !=
921 llvm::Triple::CODE16)
922 Fn->addFnAttr(
"patchable-function",
"prologue-short-redirect");
926 Fn->addFnAttr(
"no-jump-tables",
"true");
930 Fn->addFnAttr(
"no-inline-line-tables");
934 Fn->addFnAttr(
"profile-sample-accurate");
937 Fn->addFnAttr(
"use-sample-profile");
939 if (D && D->
hasAttr<CFICanonicalJumpTableAttr>())
940 Fn->addFnAttr(
"cfi-canonical-jump-table");
942 if (D && D->
hasAttr<NoProfileFunctionAttr>())
943 Fn->addFnAttr(llvm::Attribute::NoProfile);
947 if (
auto *A = D->
getAttr<FunctionReturnThunksAttr>()) {
948 switch (A->getThunkType()) {
949 case FunctionReturnThunksAttr::Kind::Keep:
951 case FunctionReturnThunksAttr::Kind::Extern:
952 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
956 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
962 EmitKernelMetadata(FD, Fn);
967 if (FD &&
SanOpts.
has(SanitizerKind::Function)) {
969 llvm::LLVMContext &Ctx = Fn->getContext();
970 llvm::MDBuilder MDB(Ctx);
972 llvm::LLVMContext::MD_func_sanitize,
973 MDB.createRTTIPointerPrologue(
980 if (
SanOpts.
has(SanitizerKind::NullabilityReturn)) {
983 if (!(
SanOpts.
has(SanitizerKind::ReturnsNonnullAttribute) &&
985 RetValNullabilityPrecondition =
1004 Fn->addFnAttr(llvm::Attribute::NoRecurse);
1007 llvm::fp::ExceptionBehavior FPExceptionBehavior =
1009 Builder.setDefaultConstrainedRounding(RM);
1010 Builder.setDefaultConstrainedExcept(FPExceptionBehavior);
1012 (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
1013 RM != llvm::RoundingMode::NearestTiesToEven))) {
1014 Builder.setIsFPConstrained(
true);
1015 Fn->addFnAttr(llvm::Attribute::StrictFP);
1022 Fn->addFnAttr(
"stackrealign");
1026 Fn->removeFnAttr(
"zero-call-used-regs");
1033 llvm::Value *Undef = llvm::UndefValue::get(
Int32Ty);
1038 Builder.SetInsertPoint(EntryBB);
1042 if (requiresReturnValueCheck()) {
1053 DI->emitFunctionStart(GD, Loc, StartLoc,
1054 DI->getFunctionType(FD, RetTy, Args),
CurFn,
1060 CurFn->addFnAttr(
"instrument-function-entry",
"__cyg_profile_func_enter");
1062 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1063 "__cyg_profile_func_enter");
1065 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1066 "__cyg_profile_func_enter_bare");
1078 Fn->addFnAttr(
"fentry-call",
"true");
1080 Fn->addFnAttr(
"instrument-function-entry-inlined",
1086 <<
"-mnop-mcount" <<
"-mfentry";
1087 Fn->addFnAttr(
"mnop-mcount");
1093 <<
"-mrecord-mcount" <<
"-mfentry";
1094 Fn->addFnAttr(
"mrecord-mcount");
1100 if (
getContext().getTargetInfo().getTriple().getArch() !=
1101 llvm::Triple::systemz)
1103 <<
"-mpacked-stack";
1104 Fn->addFnAttr(
"packed-stack");
1109 Fn->addFnAttr(
"warn-stack-size",
1122 auto AI =
CurFn->arg_begin();
1137 llvm::Function::arg_iterator EI =
CurFn->arg_end();
1142 cast<llvm::GetElementPtrInst>(Addr)->getResultElementType();
1168 if (D && D->
hasAttr<HLSLShaderAttr>())
1173 if (
const CXXMethodDecl *MD = dyn_cast_if_present<CXXMethodDecl>(D);
1202 if (FD->hasCapturedVLAType()) {
1205 auto VAT = FD->getCapturedVLAType();
1206 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
1213 CXXThisValue = CXXABIThisValue;
1217 if (CXXABIThisValue) {
1219 SkippedChecks.
set(SanitizerKind::ObjectSize,
true);
1226 SkippedChecks.
set(SanitizerKind::Null,
true);
1230 Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks);
1237 if (!FD || !FD->
hasAttr<NakedAttr>()) {
1238 for (
const VarDecl *VD : Args) {
1243 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
1244 Ty = PVD->getOriginalType();
1254 DI->EmitLocation(
Builder, StartLoc);
1259 LargestVectorWidth = VecWidth->getVectorWidth();
1265 if (
const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
1277 llvm::BasicBlock *SkipCountBB =
nullptr;
1302 if (F->isInterposable())
return;
1304 for (llvm::BasicBlock &BB : *F)
1305 for (llvm::Instruction &I : BB)
1309 F->setDoesNotThrow();
1329 bool PassedParams =
true;
1331 if (
auto Inherited = CD->getInheritedConstructor())
1337 Args.push_back(Param);
1338 if (!Param->hasAttr<PassObjectSizeAttr>())
1342 getContext(), Param->getDeclContext(), Param->getLocation(),
1345 Args.push_back(Implicit);
1349 if (MD && (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)))
1357 assert(Fn &&
"generating code for null Function");
1368 std::string FDInlineName = (Fn->getName() +
".inline").str();
1369 llvm::Module *M = Fn->getParent();
1370 llvm::Function *Clone = M->getFunction(FDInlineName);
1372 Clone = llvm::Function::Create(Fn->getFunctionType(),
1373 llvm::GlobalValue::InternalLinkage,
1374 Fn->getAddressSpace(), FDInlineName, M);
1375 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
1377 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
1387 if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) {
1388 std::string FDInlineName = (Fn->getName() +
".inline").str();
1389 llvm::Module *M = Fn->getParent();
1390 if (llvm::Function *Clone = M->getFunction(FDInlineName)) {
1391 Clone->replaceAllUsesWith(Fn);
1392 Clone->eraseFromParent();
1400 if (FD->
hasAttr<NoDebugAttr>()) {
1403 Fn->setSubprogram(
nullptr);
1405 DebugInfo =
nullptr;
1415 CurEHLocation = BodyRange.
getEnd();
1427 if (SpecDecl->hasBody(SpecDecl))
1428 Loc = SpecDecl->getLocation();
1434 if (isa<CoroutineBodyStmt>(Body))
1435 ShouldEmitLifetimeMarkers =
true;
1439 if (ShouldEmitLifetimeMarkers)
1447 if (Body && isa_and_nonnull<CoroutineBodyStmt>(Body))
1453 CurFn->addFnAttr(llvm::Attribute::MustProgress);
1457 if (isa<CXXDestructorDecl>(FD))
1459 else if (isa<CXXConstructorDecl>(FD))
1463 FD->
hasAttr<CUDAGlobalAttr>())
1465 else if (isa<CXXMethodDecl>(FD) &&
1466 cast<CXXMethodDecl>(FD)->isLambdaStaticInvoker()) {
1470 }
else if (isa<CXXMethodDecl>(FD) &&
1473 cast<CXXMethodDecl>(FD)->getParent()->getLambdaStaticInvoker() &&
1474 hasInAllocaArg(cast<CXXMethodDecl>(FD))) {
1481 }
else if (FD->
isDefaulted() && isa<CXXMethodDecl>(FD) &&
1482 (cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() ||
1483 cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) {
1490 llvm_unreachable(
"no definition for emitted function");
1500 bool ShouldEmitUnreachable =
1504 SanitizerScope SanScope(
this);
1505 llvm::Value *IsFalse =
Builder.getFalse();
1506 EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
1507 SanitizerHandler::MissingReturn,
1509 }
else if (ShouldEmitUnreachable) {
1513 if (
SanOpts.
has(SanitizerKind::Return) || ShouldEmitUnreachable) {
1515 Builder.ClearInsertionPoint();
1524 if (!
CurFn->doesNotThrow())
1533 if (!S)
return false;
1540 if (isa<LabelStmt>(S))
1545 if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
1549 if (isa<SwitchStmt>(S))
1550 IgnoreCaseStmts =
true;
1553 for (
const Stmt *SubStmt : S->children())
1565 if (!S)
return false;
1569 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S) ||
1573 if (isa<BreakStmt>(S))
1577 for (
const Stmt *SubStmt : S->children())
1585 if (!S)
return false;
1591 if (isa<IfStmt>(S) || isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
1592 isa<DoStmt>(S) || isa<ForStmt>(S) || isa<CompoundStmt>(S) ||
1593 isa<CXXForRangeStmt>(S) || isa<CXXTryStmt>(S) ||
1594 isa<ObjCForCollectionStmt>(S) || isa<ObjCAtTryStmt>(S))
1597 if (isa<DeclStmt>(S))
1600 for (
const Stmt *SubStmt : S->children())
1620 llvm::APSInt ResultInt;
1624 ResultBool = ResultInt.getBoolValue();
1632 llvm::APSInt &ResultInt,
1640 llvm::APSInt Int =
Result.Val.getInt();
1650 while (
const UnaryOperator *Op = dyn_cast<UnaryOperator>(
C->IgnoreParens())) {
1651 if (Op->getOpcode() != UO_LNot)
1653 C = Op->getSubExpr();
1655 return C->IgnoreParens();
1671 llvm::BasicBlock *FalseBlock, uint64_t TrueCount ,
1678 llvm::BasicBlock *ThenBlock =
nullptr;
1679 llvm::BasicBlock *ElseBlock =
nullptr;
1680 llvm::BasicBlock *NextBlock =
nullptr;
1697 if (LOp == BO_LAnd) {
1698 ThenBlock = CounterIncrBlock;
1699 ElseBlock = FalseBlock;
1700 NextBlock = TrueBlock;
1715 else if (LOp == BO_LOr) {
1716 ThenBlock = TrueBlock;
1717 ElseBlock = CounterIncrBlock;
1718 NextBlock = FalseBlock;
1720 llvm_unreachable(
"Expected Opcode must be that of a Logical Operator");
1744 const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock,
1748 if (
const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
1750 if (CondBOp->getOpcode() == BO_LAnd) {
1755 bool ConstantBool =
false;
1761 FalseBlock, TrueCount, LH);
1772 FalseBlock, TrueCount, LH, CondBOp);
1784 ConditionalEvaluation eval(*
this);
1801 FalseBlock, TrueCount, LH);
1807 if (CondBOp->getOpcode() == BO_LOr) {
1812 bool ConstantBool =
false;
1818 FalseBlock, TrueCount, LH);
1829 FalseBlock, TrueCount, LH, CondBOp);
1841 uint64_t RHSCount = TrueCount - LHSCount;
1843 ConditionalEvaluation eval(*
this);
1868 if (
const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
1876 if (CondUOp->getOpcode() == UO_LNot && !MCDCCondition) {
1894 ConditionalEvaluation cond(*
this);
1907 LHSScaledTrueCount = TrueCount * LHSRatio;
1916 LHSScaledTrueCount, LH, CondOp);
1923 TrueCount - LHSScaledTrueCount, LH, CondOp);
1929 if (
const CXXThrowExpr *Throw = dyn_cast<CXXThrowExpr>(Cond)) {
1949 const Expr *MCDCBaseExpr = Cond;
1956 MCDCBaseExpr = ConditionalOp;
1961 llvm::MDNode *Weights =
nullptr;
1962 llvm::MDNode *Unpredictable =
nullptr;
1969 auto *FD = dyn_cast_or_null<FunctionDecl>(
Call->getCalleeDecl());
1970 if (FD && FD->
getBuiltinID() == Builtin::BI__builtin_unpredictable) {
1972 Unpredictable = MDHelper.createUnpredictable();
1978 llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH);
1979 if (CondV != NewCondV)
1984 Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);
1987 Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights, Unpredictable);
2005 llvm::Value *sizeInChars) {
2009 llvm::Value *baseSizeInChars
2013 llvm::Value *end =
Builder.CreateInBoundsGEP(
2016 llvm::BasicBlock *originBB = CGF.
Builder.GetInsertBlock();
2024 llvm::PHINode *cur =
Builder.CreatePHI(begin.
getType(), 2,
"vla.cur");
2025 cur->addIncoming(begin.
getPointer(), originBB);
2036 Builder.CreateInBoundsGEP(CGF.
Int8Ty, cur, baseSizeInChars,
"vla.next");
2039 llvm::Value *done =
Builder.CreateICmpEQ(next, end,
"vla-init.isdone");
2040 Builder.CreateCondBr(done, contBB, loopBB);
2041 cur->addIncoming(next, loopBB);
2051 if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
2062 llvm::Value *SizeVal;
2069 dyn_cast_or_null<VariableArrayType>(
2072 SizeVal = VlaSize.NumElts;
2074 if (!eltSize.
isOne())
2095 llvm::GlobalVariable *NullVariable =
2096 new llvm::GlobalVariable(
CGM.
getModule(), NullConstant->getType(),
2098 llvm::GlobalVariable::PrivateLinkage,
2099 NullConstant, Twine());
2101 NullVariable->setAlignment(NullAlign.
getAsAlign());
2119 if (!IndirectBranch)
2125 IndirectBranch->addDestination(BB);
2126 return llvm::BlockAddress::get(
CurFn, BB);
2131 if (IndirectBranch)
return IndirectBranch->getParent();
2136 llvm::Value *DestVal = TmpBuilder.CreatePHI(
Int8PtrTy, 0,
2137 "indirect.goto.dest");
2140 IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
2141 return IndirectBranch->getParent();
2153 llvm::Value *numVLAElements =
nullptr;
2154 if (isa<VariableArrayType>(
arrayType)) {
2165 baseType = elementType;
2166 return numVLAElements;
2168 }
while (isa<VariableArrayType>(
arrayType));
2180 llvm::ConstantInt *zero =
Builder.getInt32(0);
2181 gepIndices.push_back(zero);
2186 llvm::ArrayType *llvmArrayType =
2188 while (llvmArrayType) {
2189 assert(isa<ConstantArrayType>(
arrayType));
2190 assert(cast<ConstantArrayType>(
arrayType)->getSize().getZExtValue()
2191 == llvmArrayType->getNumElements());
2193 gepIndices.push_back(zero);
2194 countFromCLAs *= llvmArrayType->getNumElements();
2198 dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
2201 "LLVM and Clang types are out-of-synch");
2210 cast<ConstantArrayType>(
arrayType)->getSize().getZExtValue();
2227 llvm::Value *numElements
2228 = llvm::ConstantInt::get(
SizeTy, countFromCLAs);
2232 numElements =
Builder.CreateNUWMul(numVLAElements, numElements);
2239 assert(vla &&
"type was not a variable array type!");
2243CodeGenFunction::VlaSizePair
2246 llvm::Value *numElements =
nullptr;
2250 elementType =
type->getElementType();
2251 llvm::Value *vlaSize = VLASizeMap[
type->getSizeExpr()];
2252 assert(vlaSize &&
"no size for VLA!");
2253 assert(vlaSize->getType() ==
SizeTy);
2256 numElements = vlaSize;
2260 numElements =
Builder.CreateNUWMul(numElements, vlaSize);
2262 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
2264 return { numElements, elementType };
2267CodeGenFunction::VlaSizePair
2270 assert(vla &&
"type was not a variable array type!");
2274CodeGenFunction::VlaSizePair
2276 llvm::Value *VlaSize = VLASizeMap[Vla->
getSizeExpr()];
2277 assert(VlaSize &&
"no size for VLA!");
2278 assert(VlaSize->getType() ==
SizeTy);
2283 assert(
type->isVariablyModifiedType() &&
2284 "Must pass variably modified type to EmitVLASizes!");
2291 assert(
type->isVariablyModifiedType());
2293 const Type *ty =
type.getTypePtr();
2296#define TYPE(Class, Base)
2297#define ABSTRACT_TYPE(Class, Base)
2298#define NON_CANONICAL_TYPE(Class, Base)
2299#define DEPENDENT_TYPE(Class, Base) case Type::Class:
2300#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
2301#include "clang/AST/TypeNodes.inc"
2302 llvm_unreachable(
"unexpected dependent type!");
2308 case Type::ExtVector:
2309 case Type::ConstantMatrix:
2313 case Type::TemplateSpecialization:
2314 case Type::ObjCTypeParam:
2315 case Type::ObjCObject:
2316 case Type::ObjCInterface:
2317 case Type::ObjCObjectPointer:
2319 llvm_unreachable(
"type class is never variably-modified!");
2321 case Type::Elaborated:
2322 type = cast<ElaboratedType>(ty)->getNamedType();
2325 case Type::Adjusted:
2326 type = cast<AdjustedType>(ty)->getAdjustedType();
2330 type = cast<DecayedType>(ty)->getPointeeType();
2334 type = cast<PointerType>(ty)->getPointeeType();
2337 case Type::BlockPointer:
2338 type = cast<BlockPointerType>(ty)->getPointeeType();
2341 case Type::LValueReference:
2342 case Type::RValueReference:
2343 type = cast<ReferenceType>(ty)->getPointeeType();
2346 case Type::MemberPointer:
2347 type = cast<MemberPointerType>(ty)->getPointeeType();
2350 case Type::ConstantArray:
2351 case Type::IncompleteArray:
2353 type = cast<ArrayType>(ty)->getElementType();
2356 case Type::VariableArray: {
2365 llvm::Value *&entry = VLASizeMap[sizeExpr];
2374 SanitizerScope SanScope(
this);
2375 llvm::Value *
Zero = llvm::Constant::getNullValue(size->getType());
2377 llvm::Value *CheckCondition =
2379 ?
Builder.CreateICmpSGT(size, Zero)
2380 :
Builder.CreateICmpUGT(size, Zero);
2381 llvm::Constant *StaticArgs[] = {
2384 EmitCheck(std::make_pair(CheckCondition, SanitizerKind::VLABound),
2385 SanitizerHandler::VLABoundNotPositive, StaticArgs, size);
2398 case Type::FunctionProto:
2399 case Type::FunctionNoProto:
2400 type = cast<FunctionType>(ty)->getReturnType();
2405 case Type::UnaryTransform:
2406 case Type::Attributed:
2407 case Type::BTFTagAttributed:
2408 case Type::SubstTemplateTypeParm:
2409 case Type::MacroQualified:
2415 case Type::Decltype:
2417 case Type::DeducedTemplateSpecialization:
2418 case Type::PackIndexing:
2422 case Type::TypeOfExpr:
2428 type = cast<AtomicType>(ty)->getValueType();
2432 type = cast<PipeType>(ty)->getElementType();
2435 }
while (
type->isVariablyModifiedType());
2439 if (
getContext().getBuiltinVaListType()->isArrayType())
2450 assert(
Init.hasValue() &&
"Invalid DeclRefExpr initializer!");
2456CodeGenFunction::PeepholeProtection
2462 if (!rvalue.
isScalar())
return PeepholeProtection();
2464 if (!isa<llvm::ZExtInst>(value))
return PeepholeProtection();
2468 llvm::Instruction *inst =
new llvm::BitCastInst(value, value->getType(),
"",
2471 PeepholeProtection protection;
2472 protection.Inst = inst;
2477 if (!protection.Inst)
return;
2480 protection.Inst->eraseFromParent();
2486 llvm::Value *Alignment,
2487 llvm::Value *OffsetValue) {
2488 if (Alignment->getType() !=
IntPtrTy)
2491 if (OffsetValue && OffsetValue->getType() !=
IntPtrTy)
2494 llvm::Value *TheCheck =
nullptr;
2496 llvm::Value *PtrIntValue =
2500 bool IsOffsetZero =
false;
2501 if (
const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
2502 IsOffsetZero = CI->isZero();
2505 PtrIntValue =
Builder.CreateSub(PtrIntValue, OffsetValue,
"offsetptr");
2508 llvm::Value *
Zero = llvm::ConstantInt::get(
IntPtrTy, 0);
2511 llvm::Value *MaskedPtr =
Builder.CreateAnd(PtrIntValue, Mask,
"maskedptr");
2512 TheCheck =
Builder.CreateICmpEQ(MaskedPtr, Zero,
"maskcond");
2514 llvm::Instruction *Assumption =
Builder.CreateAlignmentAssumption(
2520 OffsetValue, TheCheck, Assumption);
2526 llvm::Value *Alignment,
2527 llvm::Value *OffsetValue) {
2536 llvm::Value *AnnotatedVal,
2537 StringRef AnnotationStr,
2539 const AnnotateAttr *
Attr) {
2548 return Builder.CreateCall(AnnotationFn, Args);
2552 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2555 {V->getType(), CGM.ConstGlobalsPtrTy}),
2561 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2563 llvm::Type *VTy =
V->getType();
2564 auto *PTy = dyn_cast<llvm::PointerType>(VTy);
2565 unsigned AS = PTy ? PTy->getAddressSpace() : 0;
2566 llvm::PointerType *IntrinTy =
2575 if (VTy != IntrinTy)
2593 CGF->IsSanitizerScope =
false;
2597 const llvm::Twine &Name,
2598 llvm::BasicBlock *BB,
2599 llvm::BasicBlock::iterator InsertPt)
const {
2602 I->setNoSanitizeMetadata();
2606 llvm::Instruction *I,
const llvm::Twine &Name, llvm::BasicBlock *BB,
2607 llvm::BasicBlock::iterator InsertPt)
const {
2608 llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt);
2610 CGF->InsertHelper(I, Name, BB, InsertPt);
2621 if (BuiltinID == X86::BI__builtin_ia32_cmpps ||
2622 BuiltinID == X86::BI__builtin_ia32_cmpss ||
2623 BuiltinID == X86::BI__builtin_ia32_cmppd ||
2624 BuiltinID == X86::BI__builtin_ia32_cmpsd) {
2626 llvm::StringMap<bool> TargetFetureMap;
2630 if (
Result.getSExtValue() > 7 && !TargetFetureMap.lookup(
"avx"))
2656 std::string MissingFeature;
2657 llvm::StringMap<bool> CallerFeatureMap;
2667 FeatureList, CallerFeatureMap) && !IsHipStdPar) {
2673 TargetDecl->
hasAttr<TargetAttr>()) {
2676 const TargetAttr *TD = TargetDecl->
getAttr<TargetAttr>();
2681 llvm::StringMap<bool> CalleeFeatureMap;
2685 if (F[0] ==
'+' && CalleeFeatureMap.lookup(F.substr(1)))
2686 ReqFeatures.push_back(StringRef(F).substr(1));
2689 for (
const auto &F : CalleeFeatureMap) {
2692 ReqFeatures.push_back(F.getKey());
2694 if (!llvm::all_of(ReqFeatures, [&](StringRef Feature) {
2695 if (!CallerFeatureMap.lookup(Feature)) {
2696 MissingFeature = Feature.str();
2704 llvm::StringMap<bool> CalleeFeatureMap;
2707 for (
const auto &F : CalleeFeatureMap) {
2708 if (F.getValue() && (!CallerFeatureMap.lookup(F.getKey()) ||
2709 !CallerFeatureMap.find(F.getKey())->getValue()) &&
2721 llvm::IRBuilder<> IRB(
Builder.GetInsertBlock(),
Builder.GetInsertPoint());
2722 IRB.SetCurrentDebugLocation(
Builder.getCurrentDebugLocation());
2729 Callee.getAbstractInfo().getCalleeFunctionProtoType();
2734llvm::Value *CodeGenFunction::FormAArch64ResolverCondition(
2735 const MultiVersionResolverOption &RO) {
2737 for (
const StringRef &Feature : RO.Conditions.Features) {
2740 CondFeatures.push_back(Feature);
2742 if (!CondFeatures.empty()) {
2743 return EmitAArch64CpuSupports(CondFeatures);
2748llvm::Value *CodeGenFunction::FormX86ResolverCondition(
2749 const MultiVersionResolverOption &RO) {
2752 if (!RO.Conditions.Architecture.empty()) {
2753 StringRef Arch = RO.Conditions.Architecture;
2756 if (Arch.starts_with(
"x86-64"))
2762 if (!RO.Conditions.Features.empty()) {
2763 llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features);
2771 llvm::Function *Resolver,
2773 llvm::Function *FuncToReturn,
2774 bool SupportsIFunc) {
2775 if (SupportsIFunc) {
2776 Builder.CreateRet(FuncToReturn);
2781 llvm::make_pointer_range(Resolver->args()));
2783 llvm::CallInst *
Result =
Builder.CreateCall(FuncToReturn, Args);
2784 Result->setTailCallKind(llvm::CallInst::TCK_MustTail);
2786 if (Resolver->getReturnType()->isVoidTy())
2795 llvm::Triple::ArchType ArchType =
2799 case llvm::Triple::x86:
2800 case llvm::Triple::x86_64:
2803 case llvm::Triple::aarch64:
2808 assert(
false &&
"Only implemented for x86 and AArch64 targets");
2814 assert(!Options.empty() &&
"No multiversion resolver options found");
2815 assert(Options.back().Conditions.Features.size() == 0 &&
2816 "Default case must be last");
2818 assert(SupportsIFunc &&
2819 "Multiversion resolver requires target IFUNC support");
2820 bool AArch64CpuInitialized =
false;
2823 for (
const MultiVersionResolverOption &RO : Options) {
2824 Builder.SetInsertPoint(CurBlock);
2825 llvm::Value *
Condition = FormAArch64ResolverCondition(RO);
2834 if (!AArch64CpuInitialized) {
2835 Builder.SetInsertPoint(CurBlock, CurBlock->begin());
2836 EmitAArch64CpuInit();
2837 AArch64CpuInitialized =
true;
2838 Builder.SetInsertPoint(CurBlock);
2841 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
2850 Builder.SetInsertPoint(CurBlock);
2851 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
2852 TrapCall->setDoesNotReturn();
2853 TrapCall->setDoesNotThrow();
2855 Builder.ClearInsertionPoint();
2865 Builder.SetInsertPoint(CurBlock);
2868 for (
const MultiVersionResolverOption &RO : Options) {
2869 Builder.SetInsertPoint(CurBlock);
2870 llvm::Value *
Condition = FormX86ResolverCondition(RO);
2874 assert(&RO == Options.end() - 1 &&
2875 "Default or Generic case must be last");
2881 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
2890 Builder.SetInsertPoint(CurBlock);
2891 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
2892 TrapCall->setDoesNotReturn();
2893 TrapCall->setDoesNotThrow();
2895 Builder.ClearInsertionPoint();
2907 llvm::Value *OffsetValue, llvm::Value *TheCheck,
2908 llvm::Instruction *Assumption) {
2909 assert(Assumption && isa<llvm::CallInst>(Assumption) &&
2910 cast<llvm::CallInst>(Assumption)->getCalledOperand() ==
2911 llvm::Intrinsic::getDeclaration(
2912 Builder.GetInsertBlock()->getParent()->getParent(),
2913 llvm::Intrinsic::assume) &&
2914 "Assumption should be a call to llvm.assume().");
2915 assert(&(
Builder.GetInsertBlock()->back()) == Assumption &&
2916 "Assumption should be the last instruction of the basic block, "
2917 "since the basic block is still being generated.");
2929 Assumption->removeFromParent();
2932 SanitizerScope SanScope(
this);
2935 OffsetValue =
Builder.getInt1(
false);
2943 EmitCheck({std::make_pair(TheCheck, SanitizerKind::Alignment)},
2944 SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
2955 return DI->SourceLocToDebugLoc(Location);
2957 return llvm::DebugLoc();
2961CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
2972 llvm::Type *CondTy = Cond->getType();
2973 assert(CondTy->isIntegerTy(1) &&
"expecting condition to be a boolean");
2974 llvm::Function *FnExpect =
2976 llvm::Value *ExpectedValueOfCond =
2978 return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond},
2979 Cond->getName() +
".expval");
2981 llvm_unreachable(
"Unknown Likelihood");
2985 unsigned NumElementsDst,
2986 const llvm::Twine &Name) {
2987 auto *SrcTy = cast<llvm::FixedVectorType>(SrcVec->getType());
2988 unsigned NumElementsSrc = SrcTy->getNumElements();
2989 if (NumElementsSrc == NumElementsDst)
2992 std::vector<int> ShuffleMask(NumElementsDst, -1);
2993 for (
unsigned MaskIdx = 0;
2994 MaskIdx < std::min<>(NumElementsDst, NumElementsSrc); ++MaskIdx)
2995 ShuffleMask[MaskIdx] = MaskIdx;
2997 return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name);
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 CreateMultiVersionResolverReturn(CodeGenModule &CGM, llvm::Function *Resolver, CGBuilderTy &Builder, llvm::Function *FuncToReturn, bool SupportsIFunc)
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 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
static bool hasFeature(StringRef Feature, const LangOptions &LangOpts, const TargetInfo &Target)
Determine whether a translation unit built using the current language options has the given feature.
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.
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]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const LLVM_READONLY
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
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
CharUnits getAlignment() const
Return the alignment of this pointer.
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::Value * getPointer() const
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 *BB, 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="")
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 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.
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...
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 EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V, QualType Type, CharUnits Alignment=CharUnits::Zero(), SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
Emit a check that V is the address of storage of the appropriate size and alignment for an object of ...
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 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)
FieldDecl * LambdaThisCaptureField
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)
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.
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
void EmitAArch64MultiVersionResolver(llvm::Function *Resolver, ArrayRef< MultiVersionResolverOption > Options)
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
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.
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock *BB, llvm::BasicBlock::iterator InsertPt) const
CGBuilder insert helper.
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 EmitX86MultiVersionResolver(llvm::Function *Resolver, ArrayRef< MultiVersionResolverOption > Options)
void EmitFunctionBody(const Stmt *Body)
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.
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 EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerMask > > 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...
void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S)
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.
Address CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
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="")
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.
Address NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
void EmitMultiVersionResolver(llvm::Function *Resolver, ArrayRef< MultiVersionResolverOption > Options)
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.
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::Type * ConvertType(QualType T)
CodeGenTypes & getTypes() const
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T)
llvm::SmallVector< const ParmVarDecl *, 4 > FnArgs
Save Parameter Decl for coroutine.
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
Address CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
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.
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
const CGFunctionInfo * CurFnInfo
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 EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs=std::nullopt)
EmitStmt - Emit the code for the statement.
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)
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::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
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::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.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
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.
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...
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
llvm::Type * ConvertTypeForMem(QualType T, bool ForBitField=false)
ConvertTypeForMem - Convert type T into a llvm::Type.
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
bool containsOnlyLifetimeMarkers(stable_iterator Old) const
bool empty() const
Determines whether the exception-scopes stack is empty.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
static LValue MakeAddr(Address address, QualType type, ASTContext &Context, LValueBaseInfo BaseInfo, TBAAAccessInfo TBAAInfo)
Address getAddress(CodeGenFunction &CGF) 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.
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...
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.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool supportsIFunc() const
Identify whether this target supports IFuncs.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts) const
Returns target-specific min and max values VScale_Range.
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 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.
llvm::fp::ExceptionBehavior ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind)
@ Other
Other implicit parameter.
@ EST_None
no exception specification
YAML serialization mapping.
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.
Contains information gathered from parsing the contents of TargetAttr.
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