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/Transforms/Scalar/LowerExpectIntrinsic.h"
48#include "llvm/Transforms/Utils/PromoteMemToReg.h"
52using namespace CodeGen;
58 if (CGOpts.DisableLifetimeMarkers)
62 if (CGOpts.SanitizeAddressUseAfterScope ||
68 return CGOpts.OptimizationLevel != 0;
71CodeGenFunction::CodeGenFunction(
CodeGenModule &cgm,
bool suppressNewContext)
73 Builder(cgm, cgm.getModule().getContext(),
llvm::ConstantFolder(),
75 SanOpts(CGM.getLangOpts().Sanitize), CurFPFeatures(CGM.getLangOpts()),
76 DebugInfo(CGM.getModuleDebugInfo()), PGO(cgm),
77 ShouldEmitLifetimeMarkers(
79 if (!suppressNewContext)
80 CGM.getCXXABI().getMangleContext().startNewFunction();
83 SetFastMathFlags(CurFPFeatures);
86CodeGenFunction::~CodeGenFunction() {
103llvm::fp::ExceptionBehavior
111 llvm_unreachable(
"Unsupported FP Exception Behavior");
116 llvm::FastMathFlags FMF;
117 FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
118 FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
119 FMF.setNoInfs(FPFeatures.getNoHonorInfs());
120 FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
121 FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
122 FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
136 ConstructorHelper(FPFeatures);
139void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(
FPOptions FPFeatures) {
140 OldFPFeatures = CGF.CurFPFeatures;
141 CGF.CurFPFeatures = FPFeatures;
143 OldExcept = CGF.Builder.getDefaultConstrainedExcept();
144 OldRounding = CGF.Builder.getDefaultConstrainedRounding();
146 if (OldFPFeatures == FPFeatures)
149 FMFGuard.emplace(CGF.Builder);
152 CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
153 auto NewExceptionBehavior =
156 CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
158 CGF.SetFastMathFlags(FPFeatures);
160 assert((CGF.CurFuncDecl ==
nullptr || CGF.Builder.getIsFPConstrained() ||
161 isa<CXXConstructorDecl>(CGF.CurFuncDecl) ||
162 isa<CXXDestructorDecl>(CGF.CurFuncDecl) ||
163 (NewExceptionBehavior == llvm::fp::ebIgnore &&
164 NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
165 "FPConstrained should be enabled on entire function");
167 auto mergeFnAttrValue = [&](StringRef Name,
bool Value) {
169 CGF.CurFn->getFnAttribute(Name).getValueAsBool();
170 auto NewValue = OldValue &
Value;
171 if (OldValue != NewValue)
172 CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));
174 mergeFnAttrValue(
"no-infs-fp-math", FPFeatures.getNoHonorInfs());
175 mergeFnAttrValue(
"no-nans-fp-math", FPFeatures.getNoHonorNaNs());
176 mergeFnAttrValue(
"no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
179 FPFeatures.getAllowFPReassociate() && FPFeatures.getAllowReciprocal() &&
180 FPFeatures.getAllowApproxFunc() && FPFeatures.getNoSignedZero() &&
185 CGF.CurFPFeatures = OldFPFeatures;
186 CGF.Builder.setDefaultConstrainedExcept(OldExcept);
187 CGF.Builder.setDefaultConstrainedRounding(OldRounding);
222 switch (
type->getTypeClass()) {
223#define TYPE(name, parent)
224#define ABSTRACT_TYPE(name, parent)
225#define NON_CANONICAL_TYPE(name, parent) case Type::name:
226#define DEPENDENT_TYPE(name, parent) case Type::name:
227#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
228#include "clang/AST/TypeNodes.inc"
229 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
232 case Type::DeducedTemplateSpecialization:
233 llvm_unreachable(
"undeduced type in IR-generation");
238 case Type::BlockPointer:
239 case Type::LValueReference:
240 case Type::RValueReference:
241 case Type::MemberPointer:
243 case Type::ExtVector:
244 case Type::ConstantMatrix:
245 case Type::FunctionProto:
246 case Type::FunctionNoProto:
248 case Type::ObjCObjectPointer:
258 case Type::ConstantArray:
259 case Type::IncompleteArray:
260 case Type::VariableArray:
262 case Type::ObjCObject:
263 case Type::ObjCInterface:
268 type = cast<AtomicType>(
type)->getValueType();
271 llvm_unreachable(
"unknown type kind!");
278 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
281 assert(!CurBB->getTerminator() &&
"Unexpected terminated block.");
291 return llvm::DebugLoc();
298 llvm::BranchInst *BI =
300 if (BI && BI->isUnconditional() &&
304 llvm::DebugLoc Loc = BI->getDebugLoc();
305 Builder.SetInsertPoint(BI->getParent());
306 BI->eraseFromParent();
318 return llvm::DebugLoc();
323 if (!BB->use_empty()) {
331 assert(BreakContinueStack.empty() &&
332 "mismatched push/pop in break/continue stack!");
334 bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
335 && NumSimpleReturnExprs == NumReturnExprs
350 if (OnlySimpleReturnStmts)
351 DI->EmitLocation(
Builder, LastStopPoint);
353 DI->EmitLocation(
Builder, EndLoc);
361 bool HasOnlyLifetimeMarkers =
363 bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;
365 std::optional<ApplyDebugLocation> OAL;
370 if (OnlySimpleReturnStmts)
371 DI->EmitLocation(
Builder, EndLoc);
386 CurFn->addFnAttr(
"instrument-function-exit",
"__cyg_profile_func_exit");
388 CurFn->addFnAttr(
"instrument-function-exit-inlined",
389 "__cyg_profile_func_exit");
403 "did not remove all scopes from cleanup stack!");
407 if (IndirectBranch) {
414 if (!EscapedLocals.empty()) {
418 EscapeArgs.resize(EscapedLocals.size());
419 for (
auto &Pair : EscapedLocals)
420 EscapeArgs[Pair.second] = Pair.first;
421 llvm::Function *FrameEscapeFn = llvm::Intrinsic::getDeclaration(
429 Ptr->eraseFromParent();
433 if (PostAllocaInsertPt) {
434 llvm::Instruction *PostPtr = PostAllocaInsertPt;
435 PostAllocaInsertPt =
nullptr;
436 PostPtr->eraseFromParent();
441 if (IndirectBranch) {
442 llvm::PHINode *PN = cast<llvm::PHINode>(IndirectBranch->getAddress());
443 if (PN->getNumIncomingValues() == 0) {
444 PN->replaceAllUsesWith(llvm::UndefValue::get(PN->getType()));
445 PN->eraseFromParent();
454 for (
const auto &FuncletAndParent : TerminateFunclets)
460 for (
const auto &R : DeferredReplacements) {
461 if (llvm::Value *Old = R.first) {
462 Old->replaceAllUsesWith(R.second);
463 cast<llvm::Instruction>(Old)->eraseFromParent();
466 DeferredReplacements.clear();
475 llvm::DominatorTree DT(*
CurFn);
476 llvm::PromoteMemToReg(
482 for (llvm::Argument &A :
CurFn->args())
483 if (
auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
485 std::max((uint64_t)LargestVectorWidth,
486 VT->getPrimitiveSizeInBits().getKnownMinValue());
489 if (
auto *VT = dyn_cast<llvm::VectorType>(
CurFn->getReturnType()))
491 std::max((uint64_t)LargestVectorWidth,
492 VT->getPrimitiveSizeInBits().getKnownMinValue());
504 if (
getContext().getTargetInfo().getTriple().isX86())
505 CurFn->addFnAttr(
"min-legal-vector-width",
506 llvm::utostr(LargestVectorWidth));
509 std::optional<std::pair<unsigned, unsigned>> VScaleRange =
512 CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
523 if (RetAlloca && RetAlloca->use_empty()) {
524 RetAlloca->eraseFromParent();
572 llvm::Value *EncodedAddr) {
575 auto *FuncAsInt =
Builder.CreatePtrToInt(F,
IntPtrTy,
"func_addr.int");
576 auto *GOTAsInt =
Builder.CreateAdd(PCRelAsInt, FuncAsInt,
"global_addr.int");
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())
689 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
702 "Do not use a CodeGenFunction object for more than one function");
706 DidCallStackSave =
false;
708 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
715 assert(
CurFn->isDeclaration() &&
"Function already has body?");
720#define SANITIZER(NAME, ID) \
721 if (SanOpts.empty()) \
723 if (SanOpts.has(SanitizerKind::ID)) \
724 if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \
725 SanOpts.set(SanitizerKind::ID, false);
727#include "clang/Basic/Sanitizers.def"
733 bool NoSanitizeCoverage =
false;
739 if (mask & SanitizerKind::Address)
740 SanOpts.
set(SanitizerKind::KernelAddress,
false);
741 if (mask & SanitizerKind::KernelAddress)
743 if (mask & SanitizerKind::HWAddress)
744 SanOpts.
set(SanitizerKind::KernelHWAddress,
false);
745 if (mask & SanitizerKind::KernelHWAddress)
749 if (
Attr->hasCoverage())
750 NoSanitizeCoverage =
true;
754 Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds);
757 Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);
761 CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
764 if (
SanOpts.
hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
765 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
767 SanitizerKind::KernelHWAddress))
768 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
770 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
772 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
773 if (
SanOpts.
hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
774 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
777 Fn->addFnAttr(llvm::Attribute::SafeStack);
778 if (
SanOpts.
has(SanitizerKind::ShadowCallStack))
779 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
782 if (
SanOpts.
hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink))
783 Fn->addFnAttr(llvm::Attribute::OptForFuzzing);
788 if (
const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
789 IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
792 (OMD->getSelector().isUnarySelector() && II->
isStr(
".cxx_destruct"))) {
801 if (D &&
SanOpts.
has(SanitizerKind::CFIUnrelatedCast)) {
815 bool AlwaysXRayAttr =
false;
816 if (
const auto *XRayAttr = D ? D->
getAttr<XRayInstrumentAttr>() :
nullptr) {
822 Fn->addFnAttr(
"function-instrument",
"xray-always");
823 AlwaysXRayAttr =
true;
825 if (XRayAttr->neverXRayInstrument())
826 Fn->addFnAttr(
"function-instrument",
"xray-never");
827 if (
const auto *LogArgs = D->
getAttr<XRayLogArgsAttr>())
829 Fn->addFnAttr(
"xray-log-args",
830 llvm::utostr(LogArgs->getArgumentCount()));
835 "xray-instruction-threshold",
841 Fn->addFnAttr(
"xray-ignore-loops");
845 Fn->addFnAttr(
"xray-skip-exit");
849 Fn->addFnAttr(
"xray-skip-entry");
852 if (FuncGroups > 1) {
854 CurFn->getName().bytes_end());
855 auto Group = crc32(FuncName) % FuncGroups;
858 Fn->addFnAttr(
"function-instrument",
"xray-never");
865 Fn->addFnAttr(llvm::Attribute::SkipProfile);
868 Fn->addFnAttr(llvm::Attribute::NoProfile);
876 if (
const auto *
Attr =
877 D ? D->
getAttr<PatchableFunctionEntryAttr>() :
nullptr) {
878 Count =
Attr->getCount();
884 if (Count &&
Offset <= Count) {
885 Fn->addFnAttr(
"patchable-function-entry", std::to_string(Count -
Offset));
887 Fn->addFnAttr(
"patchable-function-prefix", std::to_string(
Offset));
894 getContext().getTargetInfo().getTriple().isX86() &&
895 getContext().getTargetInfo().getTriple().getEnvironment() !=
896 llvm::Triple::CODE16)
897 Fn->addFnAttr(
"patchable-function",
"prologue-short-redirect");
901 Fn->addFnAttr(
"no-jump-tables",
"true");
905 Fn->addFnAttr(
"no-inline-line-tables");
909 Fn->addFnAttr(
"profile-sample-accurate");
912 Fn->addFnAttr(
"use-sample-profile");
914 if (D && D->
hasAttr<CFICanonicalJumpTableAttr>())
915 Fn->addFnAttr(
"cfi-canonical-jump-table");
917 if (D && D->
hasAttr<NoProfileFunctionAttr>())
918 Fn->addFnAttr(llvm::Attribute::NoProfile);
922 if (
auto *A = D->
getAttr<FunctionReturnThunksAttr>()) {
923 switch (A->getThunkType()) {
924 case FunctionReturnThunksAttr::Kind::Keep:
926 case FunctionReturnThunksAttr::Kind::Extern:
927 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
931 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
937 EmitKernelMetadata(FD, Fn);
948 llvm::Constant *FTRTTIConst =
950 llvm::GlobalVariable *FTRTTIProxy =
952 llvm::LLVMContext &Ctx = Fn->getContext();
953 llvm::MDBuilder MDB(Ctx);
954 Fn->setMetadata(llvm::LLVMContext::MD_func_sanitize,
955 MDB.createRTTIPointerPrologue(PrologueSig, FTRTTIProxy));
962 if (
SanOpts.
has(SanitizerKind::NullabilityReturn)) {
965 if (!(
SanOpts.
has(SanitizerKind::ReturnsNonnullAttribute) &&
967 RetValNullabilityPrecondition =
986 Fn->addFnAttr(llvm::Attribute::NoRecurse);
989 llvm::fp::ExceptionBehavior FPExceptionBehavior =
991 Builder.setDefaultConstrainedRounding(RM);
992 Builder.setDefaultConstrainedExcept(FPExceptionBehavior);
994 (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
995 RM != llvm::RoundingMode::NearestTiesToEven))) {
996 Builder.setIsFPConstrained(
true);
997 Fn->addFnAttr(llvm::Attribute::StrictFP);
1004 Fn->addFnAttr(
"stackrealign");
1008 Fn->removeFnAttr(
"zero-call-used-regs");
1015 llvm::Value *Undef = llvm::UndefValue::get(
Int32Ty);
1020 Builder.SetInsertPoint(EntryBB);
1024 if (requiresReturnValueCheck()) {
1035 DI->emitFunctionStart(GD, Loc, StartLoc,
1036 DI->getFunctionType(FD, RetTy, Args),
CurFn,
1042 CurFn->addFnAttr(
"instrument-function-entry",
"__cyg_profile_func_enter");
1044 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1045 "__cyg_profile_func_enter");
1047 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1048 "__cyg_profile_func_enter_bare");
1060 Fn->addFnAttr(
"fentry-call",
"true");
1062 Fn->addFnAttr(
"instrument-function-entry-inlined",
1068 <<
"-mnop-mcount" <<
"-mfentry";
1069 Fn->addFnAttr(
"mnop-mcount");
1075 <<
"-mrecord-mcount" <<
"-mfentry";
1076 Fn->addFnAttr(
"mrecord-mcount");
1082 if (
getContext().getTargetInfo().getTriple().getArch() !=
1083 llvm::Triple::systemz)
1085 <<
"-mpacked-stack";
1086 Fn->addFnAttr(
"packed-stack");
1091 Fn->addFnAttr(
"warn-stack-size",
1104 auto AI =
CurFn->arg_begin();
1121 llvm::Function::arg_iterator EI =
CurFn->arg_end();
1126 cast<llvm::GetElementPtrInst>(Addr)->getResultElementType();
1152 if (D && D->
hasAttr<HLSLShaderAttr>())
1157 if (isa_and_nonnull<CXXMethodDecl>(D) &&
1158 cast<CXXMethodDecl>(D)->isInstance()) {
1185 if (FD->hasCapturedVLAType()) {
1188 auto VAT = FD->getCapturedVLAType();
1189 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
1196 CXXThisValue = CXXABIThisValue;
1200 if (CXXABIThisValue) {
1202 SkippedChecks.
set(SanitizerKind::ObjectSize,
true);
1210 SkippedChecks.
set(SanitizerKind::Null,
true);
1214 Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks);
1221 if (!FD || !FD->
hasAttr<NakedAttr>()) {
1222 for (
const VarDecl *VD : Args) {
1227 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
1228 Ty = PVD->getOriginalType();
1238 DI->EmitLocation(
Builder, StartLoc);
1243 LargestVectorWidth = VecWidth->getVectorWidth();
1248 if (
const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
1256 CurFn->addFnAttr(llvm::Attribute::MustProgress);
1265 llvm::BasicBlock *SkipCountBB =
nullptr;
1287 if (F->isInterposable())
return;
1289 for (llvm::BasicBlock &BB : *F)
1290 for (llvm::Instruction &I : BB)
1294 F->setDoesNotThrow();
1314 bool PassedParams =
true;
1316 if (
auto Inherited = CD->getInheritedConstructor())
1322 Args.push_back(Param);
1323 if (!Param->hasAttr<PassObjectSizeAttr>())
1327 getContext(), Param->getDeclContext(), Param->getLocation(),
1330 Args.push_back(Implicit);
1334 if (MD && (isa<CXXConstructorDecl>(MD) || isa<CXXDestructorDecl>(MD)))
1342 assert(Fn &&
"generating code for null Function");
1353 std::string FDInlineName = (Fn->getName() +
".inline").str();
1354 llvm::Module *M = Fn->getParent();
1355 llvm::Function *Clone = M->getFunction(FDInlineName);
1357 Clone = llvm::Function::Create(Fn->getFunctionType(),
1358 llvm::GlobalValue::InternalLinkage,
1359 Fn->getAddressSpace(), FDInlineName, M);
1360 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
1362 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
1372 if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) {
1373 std::string FDInlineName = (Fn->getName() +
".inline").str();
1374 llvm::Module *M = Fn->getParent();
1375 if (llvm::Function *Clone = M->getFunction(FDInlineName)) {
1376 Clone->replaceAllUsesWith(Fn);
1377 Clone->eraseFromParent();
1385 if (FD->
hasAttr<NoDebugAttr>()) {
1388 Fn->setSubprogram(
nullptr);
1390 DebugInfo =
nullptr;
1400 CurEHLocation = BodyRange.
getEnd();
1412 if (SpecDecl->hasBody(SpecDecl))
1413 Loc = SpecDecl->getLocation();
1419 if (isa<CoroutineBodyStmt>(Body))
1420 ShouldEmitLifetimeMarkers =
true;
1424 if (ShouldEmitLifetimeMarkers)
1432 if (Body && isa_and_nonnull<CoroutineBodyStmt>(Body))
1437 if (isa<CXXDestructorDecl>(FD))
1439 else if (isa<CXXConstructorDecl>(FD))
1443 FD->
hasAttr<CUDAGlobalAttr>())
1445 else if (isa<CXXMethodDecl>(FD) &&
1446 cast<CXXMethodDecl>(FD)->isLambdaStaticInvoker()) {
1450 }
else if (FD->
isDefaulted() && isa<CXXMethodDecl>(FD) &&
1451 (cast<CXXMethodDecl>(FD)->isCopyAssignmentOperator() ||
1452 cast<CXXMethodDecl>(FD)->isMoveAssignmentOperator())) {
1459 llvm_unreachable(
"no definition for emitted function");
1469 bool ShouldEmitUnreachable =
1473 SanitizerScope SanScope(
this);
1474 llvm::Value *IsFalse =
Builder.getFalse();
1475 EmitCheck(std::make_pair(IsFalse, SanitizerKind::Return),
1476 SanitizerHandler::MissingReturn,
1478 }
else if (ShouldEmitUnreachable) {
1482 if (
SanOpts.
has(SanitizerKind::Return) || ShouldEmitUnreachable) {
1484 Builder.ClearInsertionPoint();
1493 if (!
CurFn->doesNotThrow())
1502 if (!S)
return false;
1509 if (isa<LabelStmt>(S))
1514 if (isa<SwitchCase>(S) && !IgnoreCaseStmts)
1518 if (isa<SwitchStmt>(S))
1519 IgnoreCaseStmts =
true;
1522 for (
const Stmt *SubStmt : S->children())
1534 if (!S)
return false;
1538 if (isa<SwitchStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S) ||
1542 if (isa<BreakStmt>(S))
1546 for (
const Stmt *SubStmt : S->children())
1554 if (!S)
return false;
1560 if (isa<IfStmt>(S) || isa<SwitchStmt>(S) || isa<WhileStmt>(S) ||
1561 isa<DoStmt>(S) || isa<ForStmt>(S) || isa<CompoundStmt>(S) ||
1562 isa<CXXForRangeStmt>(S) || isa<CXXTryStmt>(S) ||
1563 isa<ObjCForCollectionStmt>(S) || isa<ObjCAtTryStmt>(S))
1566 if (isa<DeclStmt>(S))
1569 for (
const Stmt *SubStmt : S->children())
1582 llvm::APSInt ResultInt;
1586 ResultBool = ResultInt.getBoolValue();
1594 llvm::APSInt &ResultInt,
1602 llvm::APSInt Int =
Result.Val.getInt();
1615 if (
const UnaryOperator *UnOp = dyn_cast<UnaryOperator>(
C->IgnoreParens()))
1616 if (UnOp->getOpcode() == UO_LNot)
1617 C = UnOp->getSubExpr();
1619 const BinaryOperator *BOp = dyn_cast<BinaryOperator>(
C->IgnoreParens());
1629 llvm::BasicBlock *FalseBlock, uint64_t TrueCount ,
1636 llvm::BasicBlock *ThenBlock =
nullptr;
1637 llvm::BasicBlock *ElseBlock =
nullptr;
1638 llvm::BasicBlock *NextBlock =
nullptr;
1655 if (LOp == BO_LAnd) {
1656 ThenBlock = CounterIncrBlock;
1657 ElseBlock = FalseBlock;
1658 NextBlock = TrueBlock;
1673 else if (LOp == BO_LOr) {
1674 ThenBlock = TrueBlock;
1675 ElseBlock = CounterIncrBlock;
1676 NextBlock = FalseBlock;
1678 llvm_unreachable(
"Expected Opcode must be that of a Logical Operator");
1699 llvm::BasicBlock *TrueBlock,
1700 llvm::BasicBlock *FalseBlock,
1705 if (
const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
1708 if (CondBOp->getOpcode() == BO_LAnd) {
1711 bool ConstantBool =
false;
1717 FalseBlock, TrueCount, LH);
1726 FalseBlock, TrueCount, LH, CondBOp);
1736 ConditionalEvaluation eval(*
this);
1753 FalseBlock, TrueCount, LH);
1759 if (CondBOp->getOpcode() == BO_LOr) {
1762 bool ConstantBool =
false;
1768 FalseBlock, TrueCount, LH);
1777 FalseBlock, TrueCount, LH, CondBOp);
1788 uint64_t RHSCount = TrueCount - LHSCount;
1790 ConditionalEvaluation eval(*
this);
1815 if (
const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
1817 if (CondUOp->getOpcode() == UO_LNot) {
1835 ConditionalEvaluation cond(*
this);
1848 LHSScaledTrueCount = TrueCount * LHSRatio;
1857 LHSScaledTrueCount, LH);
1864 TrueCount - LHSScaledTrueCount, LH);
1870 if (
const CXXThrowExpr *Throw = dyn_cast<CXXThrowExpr>(Cond)) {
1887 llvm::MDNode *Weights =
nullptr;
1888 llvm::MDNode *Unpredictable =
nullptr;
1895 auto *FD = dyn_cast_or_null<FunctionDecl>(
Call->getCalleeDecl());
1896 if (FD && FD->
getBuiltinID() == Builtin::BI__builtin_unpredictable) {
1898 Unpredictable = MDHelper.createUnpredictable();
1904 llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH);
1905 if (CondV != NewCondV)
1910 Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);
1913 Builder.CreateCondBr(CondV, TrueBlock, FalseBlock, Weights, Unpredictable);
1931 llvm::Value *sizeInChars) {
1935 llvm::Value *baseSizeInChars
1940 llvm::Value *end =
Builder.CreateInBoundsGEP(
1943 llvm::BasicBlock *originBB = CGF.
Builder.GetInsertBlock();
1951 llvm::PHINode *cur =
Builder.CreatePHI(begin.
getType(), 2,
"vla.cur");
1952 cur->addIncoming(begin.
getPointer(), originBB);
1963 Builder.CreateInBoundsGEP(CGF.
Int8Ty, cur, baseSizeInChars,
"vla.next");
1966 llvm::Value *done =
Builder.CreateICmpEQ(next, end,
"vla-init.isdone");
1967 Builder.CreateCondBr(done, contBB, loopBB);
1968 cur->addIncoming(next, loopBB);
1978 if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
1990 llvm::Value *SizeVal;
1997 dyn_cast_or_null<VariableArrayType>(
2000 SizeVal = VlaSize.NumElts;
2002 if (!eltSize.
isOne())
2023 llvm::GlobalVariable *NullVariable =
2024 new llvm::GlobalVariable(
CGM.
getModule(), NullConstant->getType(),
2026 llvm::GlobalVariable::PrivateLinkage,
2027 NullConstant, Twine());
2029 NullVariable->setAlignment(NullAlign.
getAsAlign());
2031 Builder.getInt8Ty(), NullAlign);
2048 if (!IndirectBranch)
2054 IndirectBranch->addDestination(BB);
2055 return llvm::BlockAddress::get(
CurFn, BB);
2060 if (IndirectBranch)
return IndirectBranch->getParent();
2065 llvm::Value *DestVal = TmpBuilder.CreatePHI(
Int8PtrTy, 0,
2066 "indirect.goto.dest");
2069 IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
2070 return IndirectBranch->getParent();
2082 llvm::Value *numVLAElements =
nullptr;
2083 if (isa<VariableArrayType>(
arrayType)) {
2094 baseType = elementType;
2095 return numVLAElements;
2097 }
while (isa<VariableArrayType>(
arrayType));
2109 llvm::ConstantInt *zero =
Builder.getInt32(0);
2110 gepIndices.push_back(zero);
2115 llvm::ArrayType *llvmArrayType =
2117 while (llvmArrayType) {
2118 assert(isa<ConstantArrayType>(
arrayType));
2119 assert(cast<ConstantArrayType>(
arrayType)->getSize().getZExtValue()
2120 == llvmArrayType->getNumElements());
2122 gepIndices.push_back(zero);
2123 countFromCLAs *= llvmArrayType->getNumElements();
2127 dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
2130 "LLVM and Clang types are out-of-synch");
2139 cast<ConstantArrayType>(
arrayType)->getSize().getZExtValue();
2156 llvm::Value *numElements
2157 = llvm::ConstantInt::get(
SizeTy, countFromCLAs);
2161 numElements =
Builder.CreateNUWMul(numVLAElements, numElements);
2168 assert(vla &&
"type was not a variable array type!");
2172CodeGenFunction::VlaSizePair
2175 llvm::Value *numElements =
nullptr;
2179 elementType =
type->getElementType();
2180 llvm::Value *vlaSize = VLASizeMap[
type->getSizeExpr()];
2181 assert(vlaSize &&
"no size for VLA!");
2182 assert(vlaSize->getType() ==
SizeTy);
2185 numElements = vlaSize;
2189 numElements =
Builder.CreateNUWMul(numElements, vlaSize);
2191 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
2193 return { numElements, elementType };
2196CodeGenFunction::VlaSizePair
2199 assert(vla &&
"type was not a variable array type!");
2203CodeGenFunction::VlaSizePair
2205 llvm::Value *VlaSize = VLASizeMap[Vla->
getSizeExpr()];
2206 assert(VlaSize &&
"no size for VLA!");
2207 assert(VlaSize->getType() ==
SizeTy);
2212 assert(
type->isVariablyModifiedType() &&
2213 "Must pass variably modified type to EmitVLASizes!");
2220 assert(
type->isVariablyModifiedType());
2222 const Type *ty =
type.getTypePtr();
2225#define TYPE(Class, Base)
2226#define ABSTRACT_TYPE(Class, Base)
2227#define NON_CANONICAL_TYPE(Class, Base)
2228#define DEPENDENT_TYPE(Class, Base) case Type::Class:
2229#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
2230#include "clang/AST/TypeNodes.inc"
2231 llvm_unreachable(
"unexpected dependent type!");
2237 case Type::ExtVector:
2238 case Type::ConstantMatrix:
2242 case Type::TemplateSpecialization:
2243 case Type::ObjCTypeParam:
2244 case Type::ObjCObject:
2245 case Type::ObjCInterface:
2246 case Type::ObjCObjectPointer:
2248 llvm_unreachable(
"type class is never variably-modified!");
2250 case Type::Elaborated:
2251 type = cast<ElaboratedType>(ty)->getNamedType();
2254 case Type::Adjusted:
2255 type = cast<AdjustedType>(ty)->getAdjustedType();
2259 type = cast<DecayedType>(ty)->getPointeeType();
2263 type = cast<PointerType>(ty)->getPointeeType();
2266 case Type::BlockPointer:
2267 type = cast<BlockPointerType>(ty)->getPointeeType();
2270 case Type::LValueReference:
2271 case Type::RValueReference:
2272 type = cast<ReferenceType>(ty)->getPointeeType();
2275 case Type::MemberPointer:
2276 type = cast<MemberPointerType>(ty)->getPointeeType();
2279 case Type::ConstantArray:
2280 case Type::IncompleteArray:
2282 type = cast<ArrayType>(ty)->getElementType();
2285 case Type::VariableArray: {
2294 llvm::Value *&entry = VLASizeMap[sizeExpr];
2303 SanitizerScope SanScope(
this);
2304 llvm::Value *
Zero = llvm::Constant::getNullValue(size->getType());
2306 llvm::Value *CheckCondition =
2308 ?
Builder.CreateICmpSGT(size, Zero)
2309 :
Builder.CreateICmpUGT(size, Zero);
2310 llvm::Constant *StaticArgs[] = {
2313 EmitCheck(std::make_pair(CheckCondition, SanitizerKind::VLABound),
2314 SanitizerHandler::VLABoundNotPositive, StaticArgs, size);
2327 case Type::FunctionProto:
2328 case Type::FunctionNoProto:
2329 type = cast<FunctionType>(ty)->getReturnType();
2334 case Type::UnaryTransform:
2335 case Type::Attributed:
2336 case Type::BTFTagAttributed:
2337 case Type::SubstTemplateTypeParm:
2338 case Type::MacroQualified:
2344 case Type::Decltype:
2346 case Type::DeducedTemplateSpecialization:
2350 case Type::TypeOfExpr:
2356 type = cast<AtomicType>(ty)->getValueType();
2360 type = cast<PipeType>(ty)->getElementType();
2363 }
while (
type->isVariablyModifiedType());
2367 if (
getContext().getBuiltinVaListType()->isArrayType())
2378 assert(Init.hasValue() &&
"Invalid DeclRefExpr initializer!");
2381 Dbg->EmitGlobalVariable(E->
getDecl(), Init);
2384CodeGenFunction::PeepholeProtection
2390 if (!rvalue.
isScalar())
return PeepholeProtection();
2392 if (!isa<llvm::ZExtInst>(value))
return PeepholeProtection();
2396 llvm::Instruction *inst =
new llvm::BitCastInst(value, value->getType(),
"",
2399 PeepholeProtection protection;
2400 protection.Inst = inst;
2405 if (!protection.Inst)
return;
2408 protection.Inst->eraseFromParent();
2414 llvm::Value *Alignment,
2415 llvm::Value *OffsetValue) {
2416 if (Alignment->getType() !=
IntPtrTy)
2419 if (OffsetValue && OffsetValue->getType() !=
IntPtrTy)
2422 llvm::Value *TheCheck =
nullptr;
2424 llvm::Value *PtrIntValue =
2428 bool IsOffsetZero =
false;
2429 if (
const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
2430 IsOffsetZero = CI->isZero();
2433 PtrIntValue =
Builder.CreateSub(PtrIntValue, OffsetValue,
"offsetptr");
2436 llvm::Value *
Zero = llvm::ConstantInt::get(
IntPtrTy, 0);
2439 llvm::Value *MaskedPtr =
Builder.CreateAnd(PtrIntValue, Mask,
"maskedptr");
2440 TheCheck =
Builder.CreateICmpEQ(MaskedPtr, Zero,
"maskcond");
2442 llvm::Instruction *Assumption =
Builder.CreateAlignmentAssumption(
2448 OffsetValue, TheCheck, Assumption);
2454 llvm::Value *Alignment,
2455 llvm::Value *OffsetValue) {
2464 llvm::Value *AnnotatedVal,
2465 StringRef AnnotationStr,
2467 const AnnotateAttr *
Attr) {
2478 return Builder.CreateCall(AnnotationFn, Args);
2482 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2485 unsigned AS =
V->getType()->getPointerAddressSpace();
2486 llvm::Type *I8PtrTy =
Builder.getInt8PtrTy(AS);
2489 {I8PtrTy, CGM.ConstGlobalsPtrTy}),
2490 Builder.CreateBitCast(
V, I8PtrTy,
V->getName()),
2496 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2498 llvm::Type *VTy =
V->getType();
2499 auto *PTy = dyn_cast<llvm::PointerType>(VTy);
2500 unsigned AS = PTy ? PTy->getAddressSpace() : 0;
2501 llvm::PointerType *IntrinTy =
2502 llvm::PointerType::getWithSamePointeeType(
CGM.
Int8PtrTy, AS);
2510 if (VTy != IntrinTy)
2528 CGF->IsSanitizerScope =
false;
2532 const llvm::Twine &Name,
2533 llvm::BasicBlock *BB,
2534 llvm::BasicBlock::iterator InsertPt)
const {
2541 llvm::Instruction *I,
const llvm::Twine &Name, llvm::BasicBlock *BB,
2542 llvm::BasicBlock::iterator InsertPt)
const {
2543 llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, BB, InsertPt);
2545 CGF->InsertHelper(I, Name, BB, InsertPt);
2573 std::string MissingFeature;
2574 llvm::StringMap<bool> CallerFeatureMap;
2579 FeatureList, CallerFeatureMap)) {
2585 TargetDecl->
hasAttr<TargetAttr>()) {
2588 const TargetAttr *TD = TargetDecl->
getAttr<TargetAttr>();
2593 llvm::StringMap<bool> CalleeFeatureMap;
2597 if (F[0] ==
'+' && CalleeFeatureMap.lookup(F.substr(1)))
2598 ReqFeatures.push_back(StringRef(F).substr(1));
2601 for (
const auto &F : CalleeFeatureMap) {
2604 ReqFeatures.push_back(F.getKey());
2606 if (!llvm::all_of(ReqFeatures, [&](StringRef Feature) {
2607 if (!CallerFeatureMap.lookup(Feature)) {
2608 MissingFeature = Feature.str();
2616 llvm::StringMap<bool> CalleeFeatureMap;
2619 for (
const auto &F : CalleeFeatureMap) {
2620 if (F.getValue() && (!CallerFeatureMap.lookup(F.getKey()) ||
2621 !CallerFeatureMap.find(F.getKey())->
getValue()))
2632 llvm::IRBuilder<> IRB(
Builder.GetInsertBlock(),
Builder.GetInsertPoint());
2633 IRB.SetCurrentDebugLocation(
Builder.getCurrentDebugLocation());
2640 Callee.getAbstractInfo().getCalleeFunctionProtoType();
2645llvm::Value *CodeGenFunction::FormAArch64ResolverCondition(
2646 const MultiVersionResolverOption &RO) {
2648 for (
const StringRef &Feature : RO.Conditions.Features) {
2651 CondFeatures.push_back(Feature);
2653 if (!CondFeatures.empty()) {
2654 return EmitAArch64CpuSupports(CondFeatures);
2659llvm::Value *CodeGenFunction::FormX86ResolverCondition(
2660 const MultiVersionResolverOption &RO) {
2663 if (!RO.Conditions.Architecture.empty())
2664 Condition = EmitX86CpuIs(RO.Conditions.Architecture);
2666 if (!RO.Conditions.Features.empty()) {
2667 llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Conditions.Features);
2675 llvm::Function *Resolver,
2677 llvm::Function *FuncToReturn,
2678 bool SupportsIFunc) {
2679 if (SupportsIFunc) {
2680 Builder.CreateRet(FuncToReturn);
2685 llvm::make_pointer_range(Resolver->args()));
2687 llvm::CallInst *
Result =
Builder.CreateCall(FuncToReturn, Args);
2688 Result->setTailCallKind(llvm::CallInst::TCK_MustTail);
2690 if (Resolver->getReturnType()->isVoidTy())
2699 llvm::Triple::ArchType ArchType =
2703 case llvm::Triple::x86:
2704 case llvm::Triple::x86_64:
2707 case llvm::Triple::aarch64:
2712 assert(
false &&
"Only implemented for x86 and AArch64 targets");
2718 assert(!Options.empty() &&
"No multiversion resolver options found");
2719 assert(Options.back().Conditions.Features.size() == 0 &&
2720 "Default case must be last");
2722 assert(SupportsIFunc &&
2723 "Multiversion resolver requires target IFUNC support");
2724 bool AArch64CpuInitialized =
false;
2727 for (
const MultiVersionResolverOption &RO : Options) {
2728 Builder.SetInsertPoint(CurBlock);
2729 llvm::Value *
Condition = FormAArch64ResolverCondition(RO);
2738 if (!AArch64CpuInitialized) {
2739 Builder.SetInsertPoint(CurBlock, CurBlock->begin());
2740 EmitAArch64CpuInit();
2741 AArch64CpuInitialized =
true;
2742 Builder.SetInsertPoint(CurBlock);
2745 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
2754 Builder.SetInsertPoint(CurBlock);
2755 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
2756 TrapCall->setDoesNotReturn();
2757 TrapCall->setDoesNotThrow();
2759 Builder.ClearInsertionPoint();
2769 Builder.SetInsertPoint(CurBlock);
2772 for (
const MultiVersionResolverOption &RO : Options) {
2773 Builder.SetInsertPoint(CurBlock);
2774 llvm::Value *
Condition = FormX86ResolverCondition(RO);
2778 assert(&RO == Options.end() - 1 &&
2779 "Default or Generic case must be last");
2785 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
2794 Builder.SetInsertPoint(CurBlock);
2795 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
2796 TrapCall->setDoesNotReturn();
2797 TrapCall->setDoesNotThrow();
2799 Builder.ClearInsertionPoint();
2811 llvm::Value *OffsetValue, llvm::Value *TheCheck,
2812 llvm::Instruction *Assumption) {
2813 assert(Assumption && isa<llvm::CallInst>(Assumption) &&
2814 cast<llvm::CallInst>(Assumption)->getCalledOperand() ==
2815 llvm::Intrinsic::getDeclaration(
2816 Builder.GetInsertBlock()->getParent()->getParent(),
2817 llvm::Intrinsic::assume) &&
2818 "Assumption should be a call to llvm.assume().");
2819 assert(&(
Builder.GetInsertBlock()->back()) == Assumption &&
2820 "Assumption should be the last instruction of the basic block, "
2821 "since the basic block is still being generated.");
2833 Assumption->removeFromParent();
2836 SanitizerScope SanScope(
this);
2839 OffsetValue =
Builder.getInt1(
false);
2847 EmitCheck({std::make_pair(TheCheck, SanitizerKind::Alignment)},
2848 SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
2859 return DI->SourceLocToDebugLoc(Location);
2861 return llvm::DebugLoc();
2865CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
2876 llvm::Type *CondTy = Cond->getType();
2877 assert(CondTy->isIntegerTy(1) &&
"expecting condition to be a boolean");
2878 llvm::Function *FnExpect =
2880 llvm::Value *ExpectedValueOfCond =
2882 return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond},
2883 Cond->getName() +
".expval");
2885 llvm_unreachable(
"Unknown Likelihood");
2889 unsigned NumElementsDst,
2890 const llvm::Twine &Name) {
2891 auto *SrcTy = cast<llvm::FixedVectorType>(SrcVec->getType());
2892 unsigned NumElementsSrc = SrcTy->getNumElements();
2893 if (NumElementsSrc == NumElementsDst)
2896 std::vector<int> ShuffleMask(NumElementsDst, -1);
2897 for (
unsigned MaskIdx = 0;
2898 MaskIdx < std::min<>(NumElementsDst, NumElementsSrc); ++MaskIdx)
2899 ShuffleMask[MaskIdx] = MaskIdx;
2901 return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
static SVal getValue(SVal val, SValBuilder &svalBuilder)
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.
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.
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...
LambdaCaptureDefault getLambdaCaptureDefault() 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.
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.
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)
Address CreateElementBitCast(Address Addr, llvm::Type *Ty, const llvm::Twine &Name="")
Cast the element type of the given address to a different type, preserving information like the align...
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")
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::LoadInst * CreateLoad(Address Addr, 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.
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.
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.
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
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 ...
llvm::Value * DecodeAddrUsedInPrologue(llvm::Value *F, llvm::Value *EncodedAddr)
Decode an address used in a function prologue, encoded by EncodeAddrForUseInPrologue.
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)
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.
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
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
llvm::Constant * GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH=false)
Get the address of the RTTI descriptor for the given type.
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
llvm::GlobalVariable * GetOrCreateRTTIProxyGlobalVariable(llvm::Constant *Addr)
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.
SanitizerMetadata * getSanitizerMetadata()
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
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.
@ Other
Other implicit parameter.
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
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.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool supportsIFunc() const
Identify whether this target supports IFuncs.
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.
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.
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)
bool Call(InterpState &S, CodePtr &PC, const Function *Func)
@ NonNull
Values of this type can never be null.
@ C
Languages that the frontend can parse and compile.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
llvm::fp::ExceptionBehavior ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind)
@ 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 * Int8PtrPtrTy
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