37#include "llvm/ADT/ArrayRef.h"
38#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
39#include "llvm/IR/DataLayout.h"
40#include "llvm/IR/Dominators.h"
41#include "llvm/IR/FPEnv.h"
42#include "llvm/IR/IntrinsicInst.h"
43#include "llvm/IR/Intrinsics.h"
44#include "llvm/IR/MDBuilder.h"
45#include "llvm/IR/Operator.h"
46#include "llvm/Support/CRC.h"
47#include "llvm/Support/xxhash.h"
48#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
49#include "llvm/Transforms/Utils/PromoteMemToReg.h"
53using namespace CodeGen;
59 if (CGOpts.DisableLifetimeMarkers)
63 if (CGOpts.SanitizeAddressUseAfterScope ||
69 return CGOpts.OptimizationLevel != 0;
72CodeGenFunction::CodeGenFunction(
CodeGenModule &cgm,
bool suppressNewContext)
74 Builder(cgm, cgm.getModule().getContext(),
llvm::ConstantFolder(),
76 SanOpts(CGM.getLangOpts().Sanitize), CurFPFeatures(CGM.getLangOpts()),
77 DebugInfo(CGM.getModuleDebugInfo()), PGO(cgm),
78 ShouldEmitLifetimeMarkers(
80 if (!suppressNewContext)
81 CGM.getCXXABI().getMangleContext().startNewFunction();
84 SetFastMathFlags(CurFPFeatures);
87CodeGenFunction::~CodeGenFunction() {
104llvm::fp::ExceptionBehavior
112 llvm_unreachable(
"Unsupported FP Exception Behavior");
117 llvm::FastMathFlags FMF;
118 FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
119 FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
120 FMF.setNoInfs(FPFeatures.getNoHonorInfs());
121 FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
122 FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
123 FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
137 ConstructorHelper(FPFeatures);
140void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(
FPOptions FPFeatures) {
141 OldFPFeatures = CGF.CurFPFeatures;
142 CGF.CurFPFeatures = FPFeatures;
144 OldExcept = CGF.Builder.getDefaultConstrainedExcept();
145 OldRounding = CGF.Builder.getDefaultConstrainedRounding();
147 if (OldFPFeatures == FPFeatures)
150 FMFGuard.emplace(CGF.Builder);
153 CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
154 auto NewExceptionBehavior =
157 CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
159 CGF.SetFastMathFlags(FPFeatures);
161 assert((CGF.CurFuncDecl ==
nullptr || CGF.Builder.getIsFPConstrained() ||
162 isa<CXXConstructorDecl>(CGF.CurFuncDecl) ||
163 isa<CXXDestructorDecl>(CGF.CurFuncDecl) ||
164 (NewExceptionBehavior == llvm::fp::ebIgnore &&
165 NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
166 "FPConstrained should be enabled on entire function");
168 auto mergeFnAttrValue = [&](StringRef Name,
bool Value) {
170 CGF.CurFn->getFnAttribute(Name).getValueAsBool();
171 auto NewValue = OldValue &
Value;
172 if (OldValue != NewValue)
173 CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));
175 mergeFnAttrValue(
"no-infs-fp-math", FPFeatures.getNoHonorInfs());
176 mergeFnAttrValue(
"no-nans-fp-math", FPFeatures.getNoHonorNaNs());
177 mergeFnAttrValue(
"no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
180 FPFeatures.getAllowFPReassociate() && FPFeatures.getAllowReciprocal() &&
181 FPFeatures.getAllowApproxFunc() && FPFeatures.getNoSignedZero() &&
186 CGF.CurFPFeatures = OldFPFeatures;
187 CGF.Builder.setDefaultConstrainedExcept(OldExcept);
188 CGF.Builder.setDefaultConstrainedRounding(OldRounding);
223 switch (
type->getTypeClass()) {
224#define TYPE(name, parent)
225#define ABSTRACT_TYPE(name, parent)
226#define NON_CANONICAL_TYPE(name, parent) case Type::name:
227#define DEPENDENT_TYPE(name, parent) case Type::name:
228#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
229#include "clang/AST/TypeNodes.inc"
230 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
233 case Type::DeducedTemplateSpecialization:
234 llvm_unreachable(
"undeduced type in IR-generation");
239 case Type::BlockPointer:
240 case Type::LValueReference:
241 case Type::RValueReference:
242 case Type::MemberPointer:
244 case Type::ExtVector:
245 case Type::ConstantMatrix:
246 case Type::FunctionProto:
247 case Type::FunctionNoProto:
249 case Type::ObjCObjectPointer:
259 case Type::ConstantArray:
260 case Type::IncompleteArray:
261 case Type::VariableArray:
263 case Type::ObjCObject:
264 case Type::ObjCInterface:
269 type = cast<AtomicType>(
type)->getValueType();
272 llvm_unreachable(
"unknown type kind!");
279 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
282 assert(!CurBB->getTerminator() &&
"Unexpected terminated block.");
292 return llvm::DebugLoc();
299 llvm::BranchInst *BI =
301 if (BI && BI->isUnconditional() &&
305 llvm::DebugLoc Loc = BI->getDebugLoc();
306 Builder.SetInsertPoint(BI->getParent());
307 BI->eraseFromParent();
319 return llvm::DebugLoc();
324 if (!BB->use_empty()) {
332 assert(BreakContinueStack.empty() &&
333 "mismatched push/pop in break/continue stack!");
335 bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
336 && NumSimpleReturnExprs == NumReturnExprs
351 if (OnlySimpleReturnStmts)
352 DI->EmitLocation(
Builder, LastStopPoint);
354 DI->EmitLocation(
Builder, EndLoc);
362 bool HasOnlyLifetimeMarkers =
364 bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;
366 std::optional<ApplyDebugLocation> OAL;
371 if (OnlySimpleReturnStmts)
372 DI->EmitLocation(
Builder, EndLoc);
387 CurFn->addFnAttr(
"instrument-function-exit",
"__cyg_profile_func_exit");
389 CurFn->addFnAttr(
"instrument-function-exit-inlined",
390 "__cyg_profile_func_exit");
404 "did not remove all scopes from cleanup stack!");
408 if (IndirectBranch) {
415 if (!EscapedLocals.empty()) {
419 EscapeArgs.resize(EscapedLocals.size());
420 for (
auto &Pair : EscapedLocals)
421 EscapeArgs[Pair.second] = Pair.first;
422 llvm::Function *FrameEscapeFn = llvm::Intrinsic::getDeclaration(
430 Ptr->eraseFromParent();
434 if (PostAllocaInsertPt) {
435 llvm::Instruction *PostPtr = PostAllocaInsertPt;
436 PostAllocaInsertPt =
nullptr;
437 PostPtr->eraseFromParent();
442 if (IndirectBranch) {
443 llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
444 if (PN->getNumIncomingValues() == 0) {
445 PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
446 PN->eraseFromParent();
455 for (
const auto &FuncletAndParent : TerminateFunclets)
461 for (
const auto &R : DeferredReplacements) {
462 if (llvm::Value *Old = R.first) {
463 Old->replaceAllUsesWith(R.second);
464 cast<llvm::Instruction>(Old)->eraseFromParent();
467 DeferredReplacements.clear();
476 llvm::DominatorTree DT(*
CurFn);
477 llvm::PromoteMemToReg(
483 for (llvm::Argument &A :
CurFn->args())
484 if (
auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
486 std::max((uint64_t)LargestVectorWidth,
487 VT->getPrimitiveSizeInBits().getKnownMinValue());
490 if (
auto *VT = dyn_cast<llvm::VectorType>(
CurFn->getReturnType()))
492 std::max((uint64_t)LargestVectorWidth,
493 VT->getPrimitiveSizeInBits().getKnownMinValue());
505 if (
getContext().getTargetInfo().getTriple().isX86())
506 CurFn->addFnAttr(
"min-legal-vector-width",
507 llvm::utostr(LargestVectorWidth));
510 std::optional<std::pair<unsigned, unsigned>> VScaleRange =
513 CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
524 if (RetAlloca && RetAlloca->use_empty()) {
525 RetAlloca->eraseFromParent();
578 llvm::raw_string_ostream Out(Mangled);
580 return llvm::ConstantInt::get(
581 CGM.
Int32Ty,
static_cast<uint32_t
>(llvm::xxh3_64bits(Mangled)));
584void CodeGenFunction::EmitKernelMetadata(
const FunctionDecl *FD,
585 llvm::Function *Fn) {
586 if (!FD->
hasAttr<OpenCLKernelAttr>() && !FD->
hasAttr<CUDAGlobalAttr>())
596 if (
const VecTypeHintAttr *A = FD->
getAttr<VecTypeHintAttr>()) {
597 QualType HintQTy = A->getTypeHint();
599 bool IsSignedInteger =
602 llvm::Metadata *AttrMDArgs[] = {
603 llvm::ConstantAsMetadata::get(llvm::UndefValue::get(
605 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
606 llvm::IntegerType::get(Context, 32),
607 llvm::APInt(32, (uint64_t)(IsSignedInteger ? 1 : 0))))};
608 Fn->setMetadata(
"vec_type_hint", llvm::MDNode::get(Context, AttrMDArgs));
611 if (
const WorkGroupSizeHintAttr *A = FD->
getAttr<WorkGroupSizeHintAttr>()) {
612 llvm::Metadata *AttrMDArgs[] = {
613 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getXDim())),
614 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getYDim())),
615 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getZDim()))};
616 Fn->setMetadata(
"work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));
619 if (
const ReqdWorkGroupSizeAttr *A = FD->
getAttr<ReqdWorkGroupSizeAttr>()) {
620 llvm::Metadata *AttrMDArgs[] = {
621 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getXDim())),
622 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getYDim())),
623 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getZDim()))};
624 Fn->setMetadata(
"reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs));
627 if (
const OpenCLIntelReqdSubGroupSizeAttr *A =
628 FD->
getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
629 llvm::Metadata *AttrMDArgs[] = {
630 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getSubGroupSize()))};
631 Fn->setMetadata(
"intel_reqd_sub_group_size",
632 llvm::MDNode::get(Context, AttrMDArgs));
638 const Stmt *Body =
nullptr;
639 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(F))
641 else if (
auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(F))
642 Body = OMD->getBody();
644 if (
auto *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
645 auto LastStmt = CS->body_rbegin();
646 if (LastStmt != CS->body_rend())
647 return isa<ReturnStmt>(*LastStmt);
654 Fn->addFnAttr(
"sanitize_thread_no_checking_at_run_time");
655 Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
660bool CodeGenFunction::requiresReturnValueCheck()
const {
661 return requiresReturnValueNullabilityCheck() ||
667 auto *MD = dyn_cast_or_null<CXXMethodDecl>(D);
668 if (!MD || !MD->getDeclName().getAsIdentifierInfo() ||
669 !MD->getDeclName().getAsIdentifierInfo()->isStr(
"allocate") ||
670 (MD->getNumParams() != 1 && MD->getNumParams() != 2))
673 if (MD->parameters()[0]->getType().getCanonicalType() != Ctx.
getSizeType())
676 if (MD->getNumParams() == 2) {
677 auto *PT = MD->parameters()[1]->getType()->getAs<
PointerType>();
678 if (!PT || !PT->isVoidPointerType() ||
679 !PT->getPointeeType().isConstQualified())
691bool CodeGenFunction::hasInAllocaArg(
const CXXMethodDecl *MD) {
695 return isInAllocaArgument(CGM.getCXXABI(), P->getType());
702 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
715 "Do not use a CodeGenFunction object for more than one function");
719 DidCallStackSave =
false;
721 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
728 assert(
CurFn->isDeclaration() &&
"Function already has body?");
733#define SANITIZER(NAME, ID) \
734 if (SanOpts.empty()) \
736 if (SanOpts.has(SanitizerKind::ID)) \
737 if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \
738 SanOpts.set(SanitizerKind::ID, false);
740#include "clang/Basic/Sanitizers.def"
747 bool NoSanitizeCoverage =
false;
750 no_sanitize_mask |=
Attr->getMask();
752 if (
Attr->hasCoverage())
753 NoSanitizeCoverage =
true;
758 if (no_sanitize_mask & SanitizerKind::Address)
759 SanOpts.
set(SanitizerKind::KernelAddress,
false);
760 if (no_sanitize_mask & SanitizerKind::KernelAddress)
762 if (no_sanitize_mask & SanitizerKind::HWAddress)
763 SanOpts.
set(SanitizerKind::KernelHWAddress,
false);
764 if (no_sanitize_mask & SanitizerKind::KernelHWAddress)
768 Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds);
771 Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);
775 if (no_sanitize_mask & SanitizerKind::Thread)
776 Fn->addFnAttr(
"no_sanitize_thread");
781 CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
784 if (
SanOpts.
hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
785 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
787 SanitizerKind::KernelHWAddress))
788 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
790 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
792 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
793 if (
SanOpts.
hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
794 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
797 Fn->addFnAttr(llvm::Attribute::SafeStack);
798 if (
SanOpts.
has(SanitizerKind::ShadowCallStack))
799 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
802 if (
SanOpts.
hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink))
803 Fn->addFnAttr(llvm::Attribute::OptForFuzzing);
808 if (
const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
809 IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
812 (OMD->getSelector().isUnarySelector() && II->
isStr(
".cxx_destruct"))) {
821 if (D &&
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
835 bool AlwaysXRayAttr =
false;
836 if (
const auto *XRayAttr = D ? D->
getAttr<XRayInstrumentAttr>() :
nullptr) {
842 Fn->addFnAttr(
"function-instrument",
"xray-always");
843 AlwaysXRayAttr =
true;
845 if (XRayAttr->neverXRayInstrument())
846 Fn->addFnAttr(
"function-instrument",
"xray-never");
847 if (
const auto *LogArgs = D->
getAttr<XRayLogArgsAttr>())
849 Fn->addFnAttr(
"xray-log-args",
850 llvm::utostr(LogArgs->getArgumentCount()));
855 "xray-instruction-threshold",
861 Fn->addFnAttr(
"xray-ignore-loops");
865 Fn->addFnAttr(
"xray-skip-exit");
869 Fn->addFnAttr(
"xray-skip-entry");
872 if (FuncGroups > 1) {
874 CurFn->getName().bytes_end());
875 auto Group = crc32(FuncName) % FuncGroups;
878 Fn->addFnAttr(
"function-instrument",
"xray-never");
885 Fn->addFnAttr(llvm::Attribute::SkipProfile);
888 Fn->addFnAttr(llvm::Attribute::NoProfile);
895 unsigned Count, Offset;
896 if (
const auto *
Attr =
897 D ? D->
getAttr<PatchableFunctionEntryAttr>() :
nullptr) {
898 Count =
Attr->getCount();
899 Offset =
Attr->getOffset();
904 if (Count && Offset <= Count) {
905 Fn->addFnAttr(
"patchable-function-entry", std::to_string(Count - Offset));
907 Fn->addFnAttr(
"patchable-function-prefix", std::to_string(Offset));
914 getContext().getTargetInfo().getTriple().isX86() &&
915 getContext().getTargetInfo().getTriple().getEnvironment() !=
916 llvm::Triple::CODE16)
917 Fn->addFnAttr(
"patchable-function",
"prologue-short-redirect");
921 Fn->addFnAttr(
"no-jump-tables",
"true");
925 Fn->addFnAttr(
"no-inline-line-tables");
929 Fn->addFnAttr(
"profile-sample-accurate");
932 Fn->addFnAttr(
"use-sample-profile");
934 if (D && D->
hasAttr<CFICanonicalJumpTableAttr>())
935 Fn->addFnAttr(
"cfi-canonical-jump-table");
937 if (D && D->
hasAttr<NoProfileFunctionAttr>())
938 Fn->addFnAttr(llvm::Attribute::NoProfile);
942 if (
auto *A = D->
getAttr<FunctionReturnThunksAttr>()) {
943 switch (A->getThunkType()) {
944 case FunctionReturnThunksAttr::Kind::Keep:
946 case FunctionReturnThunksAttr::Kind::Extern:
947 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
951 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
957 EmitKernelMetadata(FD, Fn);
962 if (FD &&
SanOpts.
has(SanitizerKind::Function)) {
964 llvm::LLVMContext &Ctx = Fn->getContext();
965 llvm::MDBuilder MDB(Ctx);
967 llvm::LLVMContext::MD_func_sanitize,
968 MDB.createRTTIPointerPrologue(
975 if (
SanOpts.
has(SanitizerKind::NullabilityReturn)) {
978 if (!(
SanOpts.
has(SanitizerKind::ReturnsNonnullAttribute) &&
980 RetValNullabilityPrecondition =
999 Fn->addFnAttr(llvm::Attribute::NoRecurse);
1002 llvm::fp::ExceptionBehavior FPExceptionBehavior =
1004 Builder.setDefaultConstrainedRounding(RM);
1005 Builder.setDefaultConstrainedExcept(FPExceptionBehavior);
1007 (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
1008 RM != llvm::RoundingMode::NearestTiesToEven))) {
1009 Builder.setIsFPConstrained(
true);
1010 Fn->addFnAttr(llvm::Attribute::StrictFP);
1017 Fn->addFnAttr(
"stackrealign");
1021 Fn->removeFnAttr(
"zero-call-used-regs");
1028 llvm::Value *Undef = llvm::UndefValue::get(
Int32Ty);
1033 Builder.SetInsertPoint(EntryBB);
1037 if (requiresReturnValueCheck()) {
1048 DI->emitFunctionStart(GD, Loc, StartLoc,
1049 DI->getFunctionType(FD, RetTy, Args),
CurFn,
1055 CurFn->addFnAttr(
"instrument-function-entry",
"__cyg_profile_func_enter");
1057 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1058 "__cyg_profile_func_enter");
1060 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1061 "__cyg_profile_func_enter_bare");
1073 Fn->addFnAttr(
"fentry-call",
"true");
1075 Fn->addFnAttr(
"instrument-function-entry-inlined",
1081 <<
"-mnop-mcount" <<
"-mfentry";
1082 Fn->addFnAttr(
"mnop-mcount");
1088 <<
"-mrecord-mcount" <<
"-mfentry";
1089 Fn->addFnAttr(
"mrecord-mcount");
1095 if (
getContext().getTargetInfo().getTriple().getArch() !=
1096 llvm::Triple::systemz)
1098 <<
"-mpacked-stack";
1099 Fn->addFnAttr(
"packed-stack");
1104 Fn->addFnAttr(
"warn-stack-size",
1117 auto AI =
CurFn->arg_begin();
1132 llvm::Function::arg_iterator EI =
CurFn->arg_end();
1137 cast<llvm::GetElementPtrInst>(Addr)->getResultElementType();
1163 if (D && D->
hasAttr<HLSLShaderAttr>())
1168 if (
const CXXMethodDecl *MD = dyn_cast_if_present<CXXMethodDecl>(D);
1197 if (FD->hasCapturedVLAType()) {
1200 auto VAT = FD->getCapturedVLAType();
1201 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
1208 CXXThisValue = CXXABIThisValue;
1212 if (CXXABIThisValue) {
1214 SkippedChecks.
set(SanitizerKind::ObjectSize,
true);
1221 SkippedChecks.
set(SanitizerKind::Null,
true);
1225 Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks);
1232 if (!FD || !FD->
hasAttr<NakedAttr>()) {
1233 for (
const VarDecl *VD : Args) {
1238 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
1239 Ty = PVD->getOriginalType();
1249 DI->EmitLocation(
Builder, StartLoc);
1254 LargestVectorWidth = VecWidth->getVectorWidth();
1259 if (
const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
1271 llvm::BasicBlock *SkipCountBB =
nullptr;
1293 if (F->isInterposable())
return;
1295 for (llvm::BasicBlock &BB : *F)
1296 for (llvm::Instruction &I : BB)
1300 F->setDoesNotThrow();
1320 bool PassedParams =
true;
1322 if (
auto Inherited = CD->getInheritedConstructor())
1328 Args.push_back(Param);
1329 if (!Param->hasAttr<PassObjectSizeAttr>())
1333 getContext(), Param->getDeclContext(), Param->getLocation(),
1340 if (MD && (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)))
1348 assert(Fn &&
"generating code for null Function");
1359 std::string FDInlineName = (Fn->getName() +
".inline").str();
1360 llvm::Module *M = Fn->getParent();
1361 llvm::Function *Clone = M->getFunction(FDInlineName);
1363 Clone = llvm::Function::Create(Fn->getFunctionType(),
1364 llvm::GlobalValue::InternalLinkage,
1365 Fn->getAddressSpace(), FDInlineName, M);
1366 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
1368 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
1378 if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) {
1379 std::string FDInlineName = (Fn->getName() +
".inline").str();
1380 llvm::Module *M = Fn->getParent();
1381 if (llvm::Function *Clone = M->getFunction(FDInlineName)) {
1382 Clone->replaceAllUsesWith(Fn);
1383 Clone->eraseFromParent();
1391 if (FD->
hasAttr<NoDebugAttr>()) {
1394 Fn->setSubprogram(
nullptr);
1396 DebugInfo =
nullptr;
1406 CurEHLocation = BodyRange.
getEnd();
1418 if (SpecDecl->hasBody(SpecDecl))
1419 Loc = SpecDecl->getLocation();
1425 if (isa<CoroutineBodyStmt>(Body))
1426 ShouldEmitLifetimeMarkers =
true;
1430 if (ShouldEmitLifetimeMarkers)
1438 if (Body && isa_and_nonnull<CoroutineBodyStmt>(Body))
1444 CurFn->addFnAttr(llvm::Attribute::MustProgress);
1448 if (isa<CXXDestructorDecl>(FD))
1450 else if (isa<CXXConstructorDecl>(FD))
1454 FD->
hasAttr<CUDAGlobalAttr>())
1456 else if (isa<CXXMethodDecl>(FD) &&
1457 cast<CXXMethodDecl>(FD)->isLambdaStaticInvoker()) {
1461 }
else if (isa<CXXMethodDecl>(FD) &&
1464 cast<CXXMethodDecl>(FD)->getParent()->getLambdaStaticInvoker() &&
1465 hasInAllocaArg(cast<CXXMethodDecl>(FD))) {
1472 }
else if (FD->
isDefaulted() && isa<CXXMethodDecl>(FD) &&
1473 (cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() ||
1474 cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) {
1481 llvm_unreachable(
"no definition for emitted function");
1491 bool ShouldEmitUnreachable =
1495 SanitizerScope SanScope(
this);
1496 llvm::Value *IsFalse =
Builder.getFalse();
1497 EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
1498 SanitizerHandler::MissingReturn,
1500 }
else if (ShouldEmitUnreachable) {
1504 if (
SanOpts.
has(SanitizerKind::Return) || ShouldEmitUnreachable) {
1506 Builder.ClearInsertionPoint();
1515 if (!
CurFn->doesNotThrow())
1524 if (!S)
return false;
1531 if (isa<LabelStmt>(S))
1536 if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
1540 if (isa<SwitchStmt>(S))
1541 IgnoreCaseStmts =
true;
1544 for (
const Stmt *SubStmt : S->children())
1556 if (!S)
return false;
1560 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S) ||
1564 if (isa<BreakStmt>(S))
1568 for (
const Stmt *SubStmt : S->children())
1576 if (!S)
return false;
1582 if (isa<IfStmt>(S) || isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
1583 isa<DoStmt>(S) || isa<ForStmt>(S) || isa<CompoundStmt>(S) ||
1584 isa<CXXForRangeStmt>(S) || isa<CXXTryStmt>(S) ||
1585 isa<ObjCForCollectionStmt>(S) || isa<ObjCAtTryStmt>(S))
1588 if (isa<DeclStmt>(S))
1591 for (
const Stmt *SubStmt : S->children())
1604 llvm::APSInt ResultInt;
1608 ResultBool = ResultInt.getBoolValue();
1616 llvm::APSInt &ResultInt,
1624 llvm::APSInt Int =
Result.Val.getInt();
1637 if (
const UnaryOperator *UnOp = dyn_cast<UnaryOperator>(
C->IgnoreParens()))
1638 if (UnOp->getOpcode() == UO_LNot)
1639 C = UnOp->getSubExpr();
1641 const BinaryOperator *BOp = dyn_cast<BinaryOperator>(
C->IgnoreParens());
1651 llvm::BasicBlock *FalseBlock, uint64_t TrueCount ,
1658 llvm::BasicBlock *ThenBlock =
nullptr;
1659 llvm::BasicBlock *ElseBlock =
nullptr;
1660 llvm::BasicBlock *NextBlock =
nullptr;
1677 if (LOp == BO_LAnd) {
1678 ThenBlock = CounterIncrBlock;
1679 ElseBlock = FalseBlock;
1680 NextBlock = TrueBlock;
1695 else if (LOp == BO_LOr) {
1696 ThenBlock = TrueBlock;
1697 ElseBlock = CounterIncrBlock;
1698 NextBlock = FalseBlock;
1700 llvm_unreachable(
"Expected Opcode must be that of a Logical Operator");
1721 llvm::BasicBlock *TrueBlock,
1722 llvm::BasicBlock *FalseBlock,
1727 if (
const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
1730 if (CondBOp->getOpcode() == BO_LAnd) {
1733 bool ConstantBool =
false;
1739 FalseBlock, TrueCount, LH);
1748 FalseBlock, TrueCount, LH, CondBOp);
1758 ConditionalEvaluation eval(*
this);
1775 FalseBlock, TrueCount, LH);
1781 if (CondBOp->getOpcode() == BO_LOr) {
1784 bool ConstantBool =
false;
1790 FalseBlock, TrueCount, LH);
1799 FalseBlock, TrueCount, LH, CondBOp);
1810 uint64_t RHSCount = TrueCount - LHSCount;
1812 ConditionalEvaluation eval(*
this);
1837 if (
const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
1839 if (CondUOp->getOpcode() == UO_LNot) {
1857 ConditionalEvaluation cond(*
this);
1870 LHSScaledTrueCount = TrueCount * LHSRatio;
1879 LHSScaledTrueCount, LH);
1886 TrueCount - LHSScaledTrueCount, LH);
1892 if (
const CXXThrowExpr *Throw = dyn_cast<CXXThrowExpr>(Cond)) {
1909 llvm::MDNode *Weights =
nullptr;
1910 llvm::MDNode *Unpredictable =
nullptr;
1917 auto *FD = dyn_cast_or_null<FunctionDecl>(
Call->getCalleeDecl());
1918 if (FD && FD->
getBuiltinID() == Builtin::BI__builtin_unpredictable) {
1920 Unpredictable = MDHelper.createUnpredictable();
1926 llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH);
1927 if (CondV != NewCondV)
1932 Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);
1935 Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights, Unpredictable);
1953 llvm::Value *sizeInChars) {
1957 llvm::Value *baseSizeInChars
1961 llvm::Value *end =
Builder.CreateInBoundsGEP(
1964 llvm::BasicBlock *originBB = CGF.
Builder.GetInsertBlock();
1972 llvm::PHINode *cur =
Builder.CreatePHI(begin.
getType(), 2,
"vla.cur");
1973 cur->addIncoming(begin.
getPointer(), originBB);
1984 Builder.CreateInBoundsGEP(CGF.
Int8Ty, cur, baseSizeInChars,
"vla.next");
1987 llvm::Value *done =
Builder.CreateICmpEQ(next, end,
"vla-init.isdone");
1988 Builder.CreateCondBr(done, contBB, loopBB);
1989 cur->addIncoming(next, loopBB);
1999 if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
2010 llvm::Value *SizeVal;
2017 dyn_cast_or_null<VariableArrayType>(
2020 SizeVal = VlaSize.NumElts;
2022 if (!eltSize.
isOne())
2043 llvm::GlobalVariable *NullVariable =
2044 new llvm::GlobalVariable(
CGM.
getModule(), NullConstant->getType(),
2046 llvm::GlobalVariable::PrivateLinkage,
2047 NullConstant, Twine());
2049 NullVariable->setAlignment(NullAlign.
getAsAlign());
2067 if (!IndirectBranch)
2073 IndirectBranch->addDestination(BB);
2074 return llvm::BlockAddress::get(
CurFn, BB);
2079 if (IndirectBranch)
return IndirectBranch->getParent();
2084 llvm::Value *DestVal = TmpBuilder.CreatePHI(
Int8PtrTy, 0,
2085 "indirect.goto.dest");
2088 IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
2089 return IndirectBranch->getParent();
2101 llvm::Value *numVLAElements =
nullptr;
2102 if (isa<VariableArrayType>(
arrayType)) {
2113 baseType = elementType;
2114 return numVLAElements;
2116 }
while (isa<VariableArrayType>(
arrayType));
2128 llvm::ConstantInt *zero =
Builder.getInt32(0);
2129 gepIndices.push_back(zero);
2134 llvm::ArrayType *llvmArrayType =
2136 while (llvmArrayType) {
2137 assert(isa<ConstantArrayType>(
arrayType));
2138 assert(cast<ConstantArrayType>(
arrayType)->getSize().getZExtValue()
2139 == llvmArrayType->getNumElements());
2141 gepIndices.push_back(zero);
2142 countFromCLAs *= llvmArrayType->getNumElements();
2146 dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
2149 "LLVM and Clang types are out-of-synch");
2158 cast<ConstantArrayType>(
arrayType)->getSize().getZExtValue();
2175 llvm::Value *numElements
2176 = llvm::ConstantInt::get(
SizeTy, countFromCLAs);
2180 numElements =
Builder.CreateNUWMul(numVLAElements, numElements);
2187 assert(vla &&
"type was not a variable array type!");
2191CodeGenFunction::VlaSizePair
2194 llvm::Value *numElements =
nullptr;
2198 elementType =
type->getElementType();
2199 llvm::Value *vlaSize = VLASizeMap[
type->getSizeExpr()];
2200 assert(vlaSize &&
"no size for VLA!");
2201 assert(vlaSize->getType() ==
SizeTy);
2204 numElements = vlaSize;
2208 numElements =
Builder.CreateNUWMul(numElements, vlaSize);
2210 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
2212 return { numElements, elementType };
2215CodeGenFunction::VlaSizePair
2218 assert(vla &&
"type was not a variable array type!");
2222CodeGenFunction::VlaSizePair
2224 llvm::Value *VlaSize = VLASizeMap[Vla->
getSizeExpr()];
2225 assert(VlaSize &&
"no size for VLA!");
2226 assert(VlaSize->getType() ==
SizeTy);
2231 assert(
type->isVariablyModifiedType() &&
2232 "Must pass variably modified type to EmitVLASizes!");
2239 assert(
type->isVariablyModifiedType());
2241 const Type *ty =
type.getTypePtr();
2244#define TYPE(Class, Base)
2245#define ABSTRACT_TYPE(Class, Base)
2246#define NON_CANONICAL_TYPE(Class, Base)
2247#define DEPENDENT_TYPE(Class, Base) case Type::Class:
2248#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
2249#include "clang/AST/TypeNodes.inc"
2250 llvm_unreachable(
"unexpected dependent type!");
2256 case Type::ExtVector:
2257 case Type::ConstantMatrix:
2261 case Type::TemplateSpecialization:
2262 case Type::ObjCTypeParam:
2263 case Type::ObjCObject:
2264 case Type::ObjCInterface:
2265 case Type::ObjCObjectPointer:
2267 llvm_unreachable(
"type class is never variably-modified!");
2269 case Type::Elaborated:
2270 type = cast<ElaboratedType>(ty)->getNamedType();
2273 case Type::Adjusted:
2274 type = cast<AdjustedType>(ty)->getAdjustedType();
2278 type = cast<DecayedType>(ty)->getPointeeType();
2282 type = cast<PointerType>(ty)->getPointeeType();
2285 case Type::BlockPointer:
2286 type = cast<BlockPointerType>(ty)->getPointeeType();
2289 case Type::LValueReference:
2290 case Type::RValueReference:
2291 type = cast<ReferenceType>(ty)->getPointeeType();
2294 case Type::MemberPointer:
2295 type = cast<MemberPointerType>(ty)->getPointeeType();
2298 case Type::ConstantArray:
2299 case Type::IncompleteArray:
2301 type = cast<ArrayType>(ty)->getElementType();
2304 case Type::VariableArray: {
2313 llvm::Value *&entry = VLASizeMap[sizeExpr];
2322 SanitizerScope SanScope(
this);
2323 llvm::Value *
Zero = llvm::Constant::getNullValue(size->getType());
2325 llvm::Value *CheckCondition =
2327 ?
Builder.CreateICmpSGT(size, Zero)
2328 :
Builder.CreateICmpUGT(size, Zero);
2329 llvm::Constant *StaticArgs[] = {
2332 EmitCheck(std::make_pair(CheckCondition, SanitizerKind::VLABound),
2333 SanitizerHandler::VLABoundNotPositive, StaticArgs, size);
2346 case Type::FunctionProto:
2347 case Type::FunctionNoProto:
2348 type = cast<FunctionType>(ty)->getReturnType();
2353 case Type::UnaryTransform:
2354 case Type::Attributed:
2355 case Type::BTFTagAttributed:
2356 case Type::SubstTemplateTypeParm:
2357 case Type::MacroQualified:
2363 case Type::Decltype:
2365 case Type::DeducedTemplateSpecialization:
2369 case Type::TypeOfExpr:
2375 type = cast<AtomicType>(ty)->getValueType();
2379 type = cast<PipeType>(ty)->getElementType();
2382 }
while (
type->isVariablyModifiedType());
2386 if (
getContext().getBuiltinVaListType()->isArrayType())
2397 assert(
Init.hasValue() &&
"Invalid DeclRefExpr initializer!");
2403CodeGenFunction::PeepholeProtection
2409 if (!rvalue.
isScalar())
return PeepholeProtection();
2411 if (!isa<llvm::ZExtInst>(value))
return PeepholeProtection();
2415 llvm::Instruction *inst =
new llvm::BitCastInst(value, value->getType(),
"",
2418 PeepholeProtection protection;
2419 protection.Inst = inst;
2424 if (!protection.Inst)
return;
2427 protection.Inst->eraseFromParent();
2433 llvm::Value *Alignment,
2434 llvm::Value *OffsetValue) {
2435 if (Alignment->getType() !=
IntPtrTy)
2438 if (OffsetValue && OffsetValue->getType() !=
IntPtrTy)
2441 llvm::Value *TheCheck =
nullptr;
2443 llvm::Value *PtrIntValue =
2447 bool IsOffsetZero =
false;
2448 if (
const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
2449 IsOffsetZero = CI->isZero();
2452 PtrIntValue =
Builder.CreateSub(PtrIntValue, OffsetValue,
"offsetptr");
2455 llvm::Value *
Zero = llvm::ConstantInt::get(
IntPtrTy, 0);
2458 llvm::Value *MaskedPtr =
Builder.CreateAnd(PtrIntValue, Mask,
"maskedptr");
2459 TheCheck =
Builder.CreateICmpEQ(MaskedPtr, Zero,
"maskcond");
2461 llvm::Instruction *Assumption =
Builder.CreateAlignmentAssumption(
2467 OffsetValue, TheCheck, Assumption);
2473 llvm::Value *Alignment,
2474 llvm::Value *OffsetValue) {
2483 llvm::Value *AnnotatedVal,
2484 StringRef AnnotationStr,
2486 const AnnotateAttr *
Attr) {
2495 return Builder.CreateCall(AnnotationFn, Args);
2499 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2502 {V->getType(), CGM.ConstGlobalsPtrTy}),
2508 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2510 llvm::Type *VTy =
V->getType();
2511 auto *PTy = dyn_cast<llvm::PointerType>(VTy);
2512 unsigned AS = PTy ? PTy->getAddressSpace() : 0;
2513 llvm::PointerType *IntrinTy =
2522 if (VTy != IntrinTy)
2540 CGF->IsSanitizerScope =
false;
2544 const llvm::Twine &Name,
2545 llvm::BasicBlock *BB,
2546 llvm::BasicBlock::iterator InsertPt)
const {
2549 I->setNoSanitizeMetadata();
2553 llvm::Instruction *I,
const llvm::Twine &Name, llvm::BasicBlock *BB,
2554 llvm::BasicBlock::iterator InsertPt)
const {
2555 llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt);
2557 CGF->InsertHelper(I, Name, BB, InsertPt);
2585 std::string MissingFeature;
2586 llvm::StringMap<bool> CallerFeatureMap;
2596 FeatureList, CallerFeatureMap) && !IsHipStdPar) {
2602 TargetDecl->
hasAttr<TargetAttr>()) {
2605 const TargetAttr *TD = TargetDecl->
getAttr<TargetAttr>();
2610 llvm::StringMap<bool> CalleeFeatureMap;
2614 if (F[0] ==
'+' && CalleeFeatureMap.lookup(F.substr(1)))
2615 ReqFeatures.push_back(StringRef(F).substr(1));
2618 for (
const auto &F : CalleeFeatureMap) {
2621 ReqFeatures.push_back(F.getKey());
2623 if (!llvm::all_of(ReqFeatures, [&](StringRef Feature) {
2624 if (!CallerFeatureMap.lookup(Feature)) {
2625 MissingFeature = Feature.str();
2633 llvm::StringMap<bool> CalleeFeatureMap;
2636 for (
const auto &F : CalleeFeatureMap) {
2637 if (F.getValue() && (!CallerFeatureMap.lookup(F.getKey()) ||
2638 !CallerFeatureMap.find(F.getKey())->getValue()) &&
2650 llvm::IRBuilder<> IRB(
Builder.GetInsertBlock(),
Builder.GetInsertPoint());
2651 IRB.SetCurrentDebugLocation(
Builder.getCurrentDebugLocation());
2658 Callee.getAbstractInfo().getCalleeFunctionProtoType();
2663llvm::Value *CodeGenFunction::FormAArch64ResolverCondition(
2664 const MultiVersionResolverOption &RO) {
2666 for (
const StringRef &Feature : RO.Conditions.Features) {
2669 CondFeatures.push_back(Feature);
2671 if (!CondFeatures.empty()) {
2672 return EmitAArch64CpuSupports(CondFeatures);
2677llvm::Value *CodeGenFunction::FormX86ResolverCondition(
2678 const MultiVersionResolverOption &RO) {
2681 if (!RO.Conditions.Architecture.empty()) {
2682 StringRef Arch = RO.Conditions.Architecture;
2685 if (Arch.starts_with(
"x86-64"))
2691 if (!RO.Conditions.Features.empty()) {
2692 llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features);
2700 llvm::Function *Resolver,
2702 llvm::Function *FuncToReturn,
2703 bool SupportsIFunc) {
2704 if (SupportsIFunc) {
2705 Builder.CreateRet(FuncToReturn);
2710 llvm::make_pointer_range(Resolver->args()));
2712 llvm::CallInst *
Result =
Builder.CreateCall(FuncToReturn, Args);
2713 Result->setTailCallKind(llvm::CallInst::TCK_MustTail);
2715 if (Resolver->getReturnType()->isVoidTy())
2724 llvm::Triple::ArchType ArchType =
2728 case llvm::Triple::x86:
2729 case llvm::Triple::x86_64:
2732 case llvm::Triple::aarch64:
2737 assert(
false &&
"Only implemented for x86 and AArch64 targets");
2743 assert(!Options.empty() &&
"No multiversion resolver options found");
2744 assert(Options.back().Conditions.Features.size() == 0 &&
2745 "Default case must be last");
2747 assert(SupportsIFunc &&
2748 "Multiversion resolver requires target IFUNC support");
2749 bool AArch64CpuInitialized =
false;
2752 for (
const MultiVersionResolverOption &RO : Options) {
2753 Builder.SetInsertPoint(CurBlock);
2754 llvm::Value *
Condition = FormAArch64ResolverCondition(RO);
2763 if (!AArch64CpuInitialized) {
2764 Builder.SetInsertPoint(CurBlock, CurBlock->begin());
2765 EmitAArch64CpuInit();
2766 AArch64CpuInitialized =
true;
2767 Builder.SetInsertPoint(CurBlock);
2770 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
2779 Builder.SetInsertPoint(CurBlock);
2780 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
2781 TrapCall->setDoesNotReturn();
2782 TrapCall->setDoesNotThrow();
2784 Builder.ClearInsertionPoint();
2794 Builder.SetInsertPoint(CurBlock);
2797 for (
const MultiVersionResolverOption &RO : Options) {
2798 Builder.SetInsertPoint(CurBlock);
2799 llvm::Value *
Condition = FormX86ResolverCondition(RO);
2803 assert(&RO == Options.end() - 1 &&
2804 "Default or Generic case must be last");
2810 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
2819 Builder.SetInsertPoint(CurBlock);
2820 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
2821 TrapCall->setDoesNotReturn();
2822 TrapCall->setDoesNotThrow();
2824 Builder.ClearInsertionPoint();
2836 llvm::Value *OffsetValue, llvm::Value *TheCheck,
2837 llvm::Instruction *Assumption) {
2838 assert(Assumption && isa<llvm::CallInst>(Assumption) &&
2839 cast<llvm::CallInst>(Assumption)->getCalledOperand() ==
2840 llvm::Intrinsic::getDeclaration(
2841 Builder.GetInsertBlock()->getParent()->getParent(),
2842 llvm::Intrinsic::assume) &&
2843 "Assumption should be a call to llvm.assume().");
2844 assert(&(
Builder.GetInsertBlock()->back()) == Assumption &&
2845 "Assumption should be the last instruction of the basic block, "
2846 "since the basic block is still being generated.");
2858 Assumption->removeFromParent();
2861 SanitizerScope SanScope(
this);
2864 OffsetValue =
Builder.getInt1(
false);
2872 EmitCheck({std::make_pair(TheCheck, SanitizerKind::Alignment)},
2873 SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
2884 return DI->SourceLocToDebugLoc(Location);
2886 return llvm::DebugLoc();
2890CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
2901 llvm::Type *CondTy = Cond->getType();
2902 assert(CondTy->isIntegerTy(1) &&
"expecting condition to be a boolean");
2903 llvm::Function *FnExpect =
2905 llvm::Value *ExpectedValueOfCond =
2907 return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond},
2908 Cond->getName() +
".expval");
2910 llvm_unreachable(
"Unknown Likelihood");
2914 unsigned NumElementsDst,
2915 const llvm::Twine &Name) {
2916 auto *SrcTy = cast<llvm::FixedVectorType>(SrcVec->getType());
2917 unsigned NumElementsSrc = SrcTy->getNumElements();
2918 if (NumElementsSrc == NumElementsDst)
2921 std::vector<int> ShuffleMask(NumElementsDst, -1);
2922 for (
unsigned MaskIdx = 0;
2923 MaskIdx < std::min<>(NumElementsDst, NumElementsSrc); ++MaskIdx)
2924 ShuffleMask[MaskIdx] = MaskIdx;
2926 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....
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.
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]).
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.
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 EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
void EmitVarAnnotations(const VarDecl *D, llvm::Value *V)
Emit local annotations for the local variable V, declared by D.
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.
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,...
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 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...
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.
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.
FPExceptionModeKind
Possible floating point exception behavior.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
@ FPE_MayTrap
Transformations do not cause new exceptions but may hide some.
@ FPE_Strict
Strictly preserve the floating-point exception semantics.
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)
@ 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.
@ Implicit
New-expression has no written initializer, but has an implicit one.
@ EST_None
no exception specification
YAML serialization mapping.
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