39#include "llvm/ADT/ArrayRef.h"
40#include "llvm/ADT/ScopeExit.h"
41#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
42#include "llvm/IR/DataLayout.h"
43#include "llvm/IR/Dominators.h"
44#include "llvm/IR/FPEnv.h"
45#include "llvm/IR/Instruction.h"
46#include "llvm/IR/IntrinsicInst.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/IntrinsicsPowerPC.h"
49#include "llvm/IR/MDBuilder.h"
50#include "llvm/Support/CRC.h"
51#include "llvm/Support/SipHash.h"
52#include "llvm/Support/xxhash.h"
53#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
54#include "llvm/Transforms/Utils/PromoteMemToReg.h"
64 if (CGOpts.DisableLifetimeMarkers)
68 if (CGOpts.SanitizeAddressUseAfterScope ||
75 return CGOpts.OptimizationLevel != 0;
78CodeGenFunction::CodeGenFunction(
CodeGenModule &cgm,
bool suppressNewContext)
82 DebugInfo(
CGM.getModuleDebugInfo()),
84 ShouldEmitLifetimeMarkers(
86 if (!suppressNewContext)
87 CGM.getCXXABI().getMangleContext().startNewFunction();
96 "missed to deactivate a cleanup");
99 CGM.getOpenMPRuntime().functionFinished(*
this);
106 if (
CGM.getLangOpts().OpenMPIRBuilder &&
CurFn)
107 CGM.getOpenMPRuntime().getOMPBuilder().finalize(
CurFn);
112llvm::fp::ExceptionBehavior
120 llvm_unreachable(
"Unsupported FP Exception Behavior");
125 llvm::FastMathFlags FMF;
126 FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
127 FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
128 FMF.setNoInfs(FPFeatures.getNoHonorInfs());
129 FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
130 FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
131 FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
145 ConstructorHelper(FPFeatures);
148void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(
FPOptions FPFeatures) {
149 OldFPFeatures = CGF.CurFPFeatures;
150 CGF.CurFPFeatures = FPFeatures;
152 OldExcept = CGF.Builder.getDefaultConstrainedExcept();
153 OldRounding = CGF.Builder.getDefaultConstrainedRounding();
155 if (OldFPFeatures == FPFeatures)
158 FMFGuard.emplace(CGF.Builder);
161 CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
162 auto NewExceptionBehavior =
164 CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
166 CGF.SetFastMathFlags(FPFeatures);
168 assert((CGF.CurFuncDecl ==
nullptr || CGF.Builder.getIsFPConstrained() ||
171 (NewExceptionBehavior == llvm::fp::ebIgnore &&
172 NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
173 "FPConstrained should be enabled on entire function");
175 auto mergeFnAttrValue = [&](StringRef Name,
bool Value) {
177 CGF.CurFn->getFnAttribute(Name).getValueAsBool();
178 auto NewValue = OldValue &
Value;
179 if (OldValue != NewValue)
180 CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));
182 mergeFnAttrValue(
"no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
186 CGF.CurFPFeatures = OldFPFeatures;
187 CGF.Builder.setDefaultConstrainedExcept(OldExcept);
188 CGF.Builder.setDefaultConstrainedRounding(OldRounding);
202 nullptr, IsKnownNonNull)
210 return ::makeNaturalAlignAddrLValue(
V, T,
false,
217 return ::makeNaturalAlignAddrLValue(
V, T,
true,
223 return ::makeNaturalAlignAddrLValue(
V, T,
false,
229 return ::makeNaturalAlignAddrLValue(
V, T,
true,
234 return CGM.getTypes().ConvertTypeForMem(T);
238 return CGM.getTypes().ConvertType(T);
242 llvm::Type *LLVMTy) {
243 return CGM.getTypes().convertTypeForLoadStore(ASTTy, LLVMTy);
249 switch (
type->getTypeClass()) {
250#define TYPE(name, parent)
251#define ABSTRACT_TYPE(name, parent)
252#define NON_CANONICAL_TYPE(name, parent) case Type::name:
253#define DEPENDENT_TYPE(name, parent) case Type::name:
254#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
255#include "clang/AST/TypeNodes.inc"
256 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
259 case Type::DeducedTemplateSpecialization:
260 llvm_unreachable(
"undeduced type in IR-generation");
265 case Type::BlockPointer:
266 case Type::LValueReference:
267 case Type::RValueReference:
268 case Type::MemberPointer:
270 case Type::ExtVector:
271 case Type::ConstantMatrix:
272 case Type::FunctionProto:
273 case Type::FunctionNoProto:
275 case Type::ObjCObjectPointer:
278 case Type::HLSLAttributedResource:
279 case Type::HLSLInlineSpirv:
280 case Type::OverflowBehavior:
288 case Type::ConstantArray:
289 case Type::IncompleteArray:
290 case Type::VariableArray:
292 case Type::ObjCObject:
293 case Type::ObjCInterface:
294 case Type::ArrayParameter:
302 llvm_unreachable(
"unknown type kind!");
309 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
312 assert(!CurBB->hasTerminator() &&
"Unexpected terminated block.");
316 if (CurBB->empty() ||
ReturnBlock.getBlock()->use_empty()) {
322 return llvm::DebugLoc();
330 dyn_cast<llvm::UncondBrInst>(*
ReturnBlock.getBlock()->user_begin());
331 if (BI && BI->getSuccessor(0) ==
ReturnBlock.getBlock()) {
334 llvm::DebugLoc Loc = BI->getDebugLoc();
335 Builder.SetInsertPoint(BI->getParent());
336 BI->eraseFromParent();
348 return llvm::DebugLoc();
353 if (!BB->use_empty()) {
361 assert(BreakContinueStack.empty() &&
362 "mismatched push/pop in break/continue stack!");
364 "mismatched push/pop of cleanups in EHStack!");
366 "mismatched activate/deactivate of cleanups!");
368 if (
CGM.shouldEmitConvergenceTokens()) {
371 "mismatched push/pop in convergence stack!");
374 bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
375 && NumSimpleReturnExprs == NumReturnExprs
390 if (OnlySimpleReturnStmts)
391 DI->EmitLocation(
Builder, LastStopPoint);
393 DI->EmitLocation(
Builder, EndLoc);
401 bool HasOnlyNoopCleanups =
403 bool EmitRetDbgLoc = !HasCleanups || HasOnlyNoopCleanups;
405 std::optional<ApplyDebugLocation> OAL;
410 if (OnlySimpleReturnStmts)
411 DI->EmitLocation(
Builder, EndLoc);
425 if (
CGM.getCodeGenOpts().InstrumentFunctions)
426 CurFn->addFnAttr(
"instrument-function-exit",
"__cyg_profile_func_exit");
427 if (
CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)
428 CurFn->addFnAttr(
"instrument-function-exit-inlined",
429 "__cyg_profile_func_exit");
438 uint64_t RetKeyInstructionsAtomGroup = Loc ? Loc->getAtomGroup() : 0;
441 RetKeyInstructionsAtomGroup);
445 "did not remove all scopes from cleanup stack!");
449 if (IndirectBranch) {
456 if (!EscapedLocals.empty()) {
460 EscapeArgs.resize(EscapedLocals.size());
461 for (
auto &Pair : EscapedLocals)
462 EscapeArgs[Pair.second] = Pair.first;
463 llvm::Function *FrameEscapeFn = llvm::Intrinsic::getOrInsertDeclaration(
464 &
CGM.getModule(), llvm::Intrinsic::localescape);
471 Ptr->eraseFromParent();
475 if (PostAllocaInsertPt) {
476 llvm::Instruction *PostPtr = PostAllocaInsertPt;
477 PostAllocaInsertPt =
nullptr;
478 PostPtr->eraseFromParent();
483 if (IndirectBranch) {
485 if (PN->getNumIncomingValues() == 0) {
486 PN->replaceAllUsesWith(llvm::PoisonValue::get(PN->getType()));
487 PN->eraseFromParent();
496 for (
const auto &FuncletAndParent : TerminateFunclets)
499 if (
CGM.getCodeGenOpts().EmitDeclMetadata)
502 for (
const auto &R : DeferredReplacements) {
503 if (llvm::Value *Old = R.first) {
504 Old->replaceAllUsesWith(R.second);
508 DeferredReplacements.clear();
517 llvm::DominatorTree DT(*
CurFn);
518 llvm::PromoteMemToReg(
524 for (llvm::Argument &A :
CurFn->args())
525 if (
auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
527 std::max((uint64_t)LargestVectorWidth,
528 VT->getPrimitiveSizeInBits().getKnownMinValue());
531 if (
auto *VT = dyn_cast<llvm::VectorType>(
CurFn->getReturnType()))
533 std::max((uint64_t)LargestVectorWidth,
534 VT->getPrimitiveSizeInBits().getKnownMinValue());
536 if (
CurFnInfo->getMaxVectorWidth() > LargestVectorWidth)
537 LargestVectorWidth =
CurFnInfo->getMaxVectorWidth();
547 CurFn->addFnAttr(
"min-legal-vector-width",
548 llvm::utostr(LargestVectorWidth));
557 dyn_cast<llvm::AllocaInst>(
ReturnValue.emitRawPointer(*
this));
558 if (RetAlloca && RetAlloca->use_empty()) {
559 RetAlloca->eraseFromParent();
568 if (!
CGM.getCodeGenOpts().InstrumentFunctions &&
569 !
CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining &&
570 !
CGM.getCodeGenOpts().InstrumentFunctionEntryBare)
580 return CurFuncDecl->hasAttr<DisableSanitizerInstrumentationAttr>();
586 return CGM.getCodeGenOpts().XRayInstrumentFunctions;
592 return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
593 (
CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents ||
594 CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
599 return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
600 (
CGM.getCodeGenOpts().XRayAlwaysEmitTypedEvents ||
601 CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
612 llvm::raw_string_ostream Out(Mangled);
613 CGM.getCXXABI().getMangleContext().mangleCanonicalTypeName(Ty, Out,
false);
614 return llvm::ConstantInt::get(
615 CGM.Int32Ty,
static_cast<uint32_t
>(llvm::xxh3_64bits(Mangled)));
618void CodeGenFunction::EmitKernelMetadata(
const FunctionDecl *FD,
619 llvm::Function *Fn) {
620 if (!FD->
hasAttr<DeviceKernelAttr>() && !FD->
hasAttr<CUDAGlobalAttr>())
632 if (
const VecTypeHintAttr *A = FD->
getAttr<VecTypeHintAttr>()) {
633 QualType HintQTy = A->getTypeHint();
635 bool IsSignedInteger =
637 (HintEltQTy && HintEltQTy->
getElementType()->isSignedIntegerType());
638 llvm::Metadata *AttrMDArgs[] = {
639 llvm::ConstantAsMetadata::get(llvm::PoisonValue::get(
641 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
642 llvm::IntegerType::get(Context, 32),
643 llvm::APInt(32, (uint64_t)(IsSignedInteger ? 1 : 0))))};
644 Fn->setMetadata(
"vec_type_hint", llvm::MDNode::get(Context, AttrMDArgs));
647 if (
const WorkGroupSizeHintAttr *A = FD->
getAttr<WorkGroupSizeHintAttr>()) {
648 auto Eval = [&](
Expr *E) {
649 return E->EvaluateKnownConstInt(FD->
getASTContext()).getExtValue();
651 llvm::Metadata *AttrMDArgs[] = {
652 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getXDim()))),
653 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getYDim()))),
654 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getZDim())))};
655 Fn->setMetadata(
"work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));
658 if (
const ReqdWorkGroupSizeAttr *A = FD->
getAttr<ReqdWorkGroupSizeAttr>()) {
659 auto Eval = [&](Expr *E) {
660 return E->EvaluateKnownConstInt(FD->
getASTContext()).getExtValue();
662 llvm::Metadata *AttrMDArgs[] = {
663 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getXDim()))),
664 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getYDim()))),
665 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getZDim())))};
666 Fn->setMetadata(
"reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs));
669 if (
const OpenCLIntelReqdSubGroupSizeAttr *A =
670 FD->
getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
671 llvm::Metadata *AttrMDArgs[] = {
672 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getSubGroupSize()))};
673 Fn->setMetadata(
"intel_reqd_sub_group_size",
674 llvm::MDNode::get(Context, AttrMDArgs));
680 const Stmt *Body =
nullptr;
681 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(F))
683 else if (
auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(F))
684 Body = OMD->getBody();
686 if (
auto *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
687 auto LastStmt = CS->body_rbegin();
688 if (LastStmt != CS->body_rend())
695 if (
SanOpts.has(SanitizerKind::Thread)) {
696 Fn->addFnAttr(
"sanitize_thread_no_checking_at_run_time");
697 Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
702bool CodeGenFunction::requiresReturnValueCheck()
const {
703 return requiresReturnValueNullabilityCheck() ||
709 auto *MD = dyn_cast_or_null<CXXMethodDecl>(D);
710 if (!MD || !MD->getDeclName().getAsIdentifierInfo() ||
711 !MD->getDeclName().getAsIdentifierInfo()->isStr(
"allocate") ||
712 (MD->getNumParams() != 1 && MD->getNumParams() != 2))
718 if (MD->getNumParams() == 2) {
719 auto *PT = MD->parameters()[1]->getType()->getAs<
PointerType>();
720 if (!PT || !PT->isVoidPointerType() ||
721 !PT->getPointeeType().isConstQualified())
728bool CodeGenFunction::isInAllocaArgument(
CGCXXABI &ABI, QualType Ty) {
733bool CodeGenFunction::hasInAllocaArg(
const CXXMethodDecl *MD) {
736 llvm::any_of(MD->
parameters(), [&](ParmVarDecl *P) {
737 return isInAllocaArgument(CGM.getCXXABI(), P->getType());
744 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
757 "Do not use a CodeGenFunction object for more than one function");
761 DidCallStackSave =
false;
763 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
770 assert(
CurFn->isDeclaration() &&
"Function already has body?");
775#define SANITIZER(NAME, ID) \
776 if (SanOpts.empty()) \
778 if (SanOpts.has(SanitizerKind::ID)) \
779 if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \
780 SanOpts.set(SanitizerKind::ID, false);
782#include "clang/Basic/Sanitizers.def"
787 const bool SanitizeBounds =
SanOpts.hasOneOf(SanitizerKind::Bounds);
789 bool NoSanitizeCoverage =
false;
792 no_sanitize_mask |=
Attr->getMask();
794 if (
Attr->hasCoverage())
795 NoSanitizeCoverage =
true;
799 SanOpts.Mask &= ~no_sanitize_mask;
800 if (no_sanitize_mask & SanitizerKind::Address)
801 SanOpts.set(SanitizerKind::KernelAddress,
false);
802 if (no_sanitize_mask & SanitizerKind::KernelAddress)
803 SanOpts.set(SanitizerKind::Address,
false);
804 if (no_sanitize_mask & SanitizerKind::HWAddress)
805 SanOpts.set(SanitizerKind::KernelHWAddress,
false);
806 if (no_sanitize_mask & SanitizerKind::KernelHWAddress)
807 SanOpts.set(SanitizerKind::HWAddress,
false);
809 if (SanitizeBounds && !
SanOpts.hasOneOf(SanitizerKind::Bounds))
810 Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds);
812 if (NoSanitizeCoverage &&
CGM.getCodeGenOpts().hasSanitizeCoverage())
813 Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);
816 if (
CGM.getCodeGenOpts().hasSanitizeBinaryMetadata()) {
817 if (no_sanitize_mask & SanitizerKind::Thread)
818 Fn->addFnAttr(
"no_sanitize_thread");
823 CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
826 if (
SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
827 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
828 if (
SanOpts.hasOneOf(SanitizerKind::HWAddress |
829 SanitizerKind::KernelHWAddress))
830 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
831 if (
SanOpts.has(SanitizerKind::MemtagStack))
832 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
833 if (
SanOpts.has(SanitizerKind::Thread))
834 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
835 if (
SanOpts.has(SanitizerKind::Type))
836 Fn->addFnAttr(llvm::Attribute::SanitizeType);
837 if (
SanOpts.has(SanitizerKind::NumericalStability))
838 Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
839 if (
SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
840 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
841 if (
SanOpts.has(SanitizerKind::AllocToken))
842 Fn->addFnAttr(llvm::Attribute::SanitizeAllocToken);
844 if (
SanOpts.has(SanitizerKind::SafeStack))
845 Fn->addFnAttr(llvm::Attribute::SafeStack);
846 if (
SanOpts.has(SanitizerKind::ShadowCallStack))
847 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
849 if (
SanOpts.has(SanitizerKind::Realtime))
853 Fn->addFnAttr(llvm::Attribute::SanitizeRealtime);
855 Fn->addFnAttr(llvm::Attribute::SanitizeRealtimeBlocking);
859 if (
SanOpts.hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink))
860 Fn->addFnAttr(llvm::Attribute::OptForFuzzing);
864 if (
SanOpts.has(SanitizerKind::Thread)) {
865 if (
const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
866 const IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
869 (OMD->getSelector().isUnarySelector() && II->
isStr(
".cxx_destruct"))) {
878 if (D &&
SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
886 if (D &&
SanOpts.has(SanitizerKind::Null))
892 bool AlwaysXRayAttr =
false;
893 if (
const auto *XRayAttr = D ? D->
getAttr<XRayInstrumentAttr>() :
nullptr) {
894 if (
CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
896 CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
899 Fn->addFnAttr(
"function-instrument",
"xray-always");
900 AlwaysXRayAttr =
true;
902 if (XRayAttr->neverXRayInstrument())
903 Fn->addFnAttr(
"function-instrument",
"xray-never");
904 if (
const auto *LogArgs = D->
getAttr<XRayLogArgsAttr>())
906 Fn->addFnAttr(
"xray-log-args",
907 llvm::utostr(LogArgs->getArgumentCount()));
912 "xray-instruction-threshold",
913 llvm::itostr(
CGM.getCodeGenOpts().XRayInstructionThreshold));
917 if (
CGM.getCodeGenOpts().XRayIgnoreLoops)
918 Fn->addFnAttr(
"xray-ignore-loops");
920 if (!
CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
922 Fn->addFnAttr(
"xray-skip-exit");
924 if (!
CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
926 Fn->addFnAttr(
"xray-skip-entry");
928 auto FuncGroups =
CGM.getCodeGenOpts().XRayTotalFunctionGroups;
929 if (FuncGroups > 1) {
931 CurFn->getName().bytes_end());
932 auto Group = crc32(FuncName) % FuncGroups;
933 if (Group !=
CGM.getCodeGenOpts().XRaySelectedFunctionGroup &&
935 Fn->addFnAttr(
"function-instrument",
"xray-never");
939 if (
CGM.getCodeGenOpts().getProfileInstr() !=
940 llvm::driver::ProfileInstrKind::ProfileNone) {
941 switch (
CGM.isFunctionBlockedFromProfileInstr(Fn, Loc)) {
943 Fn->addFnAttr(llvm::Attribute::SkipProfile);
946 Fn->addFnAttr(llvm::Attribute::NoProfile);
953 unsigned Count, Offset;
955 if (
const auto *
Attr =
956 D ? D->
getAttr<PatchableFunctionEntryAttr>() :
nullptr) {
957 Count =
Attr->getCount();
958 Offset =
Attr->getOffset();
959 Section =
Attr->getSection();
961 Count =
CGM.getCodeGenOpts().PatchableFunctionEntryCount;
962 Offset =
CGM.getCodeGenOpts().PatchableFunctionEntryOffset;
965 Section =
CGM.getCodeGenOpts().PatchableFunctionEntrySection;
966 if (Count && Offset <= Count) {
967 Fn->addFnAttr(
"patchable-function-entry", std::to_string(Count - Offset));
969 Fn->addFnAttr(
"patchable-function-prefix", std::to_string(Offset));
970 if (!Section.empty())
971 Fn->addFnAttr(
"patchable-function-entry-section", Section);
977 if (
CGM.getCodeGenOpts().HotPatch &&
980 llvm::Triple::CODE16)
981 Fn->addFnAttr(
"patchable-function",
"prologue-short-redirect");
984 if (
CGM.getCodeGenOpts().NoUseJumpTables)
985 Fn->addFnAttr(
"no-jump-tables",
"true");
988 if (
CGM.getCodeGenOpts().NoInlineLineTables)
989 Fn->addFnAttr(
"no-inline-line-tables");
992 if (
CGM.getCodeGenOpts().ProfileSampleAccurate)
993 Fn->addFnAttr(
"profile-sample-accurate");
995 if (!
CGM.getCodeGenOpts().SampleProfileFile.empty())
996 Fn->addFnAttr(
"use-sample-profile");
998 if (D && D->
hasAttr<CFICanonicalJumpTableAttr>())
999 Fn->addFnAttr(
"cfi-canonical-jump-table");
1001 if (D && D->
hasAttr<NoProfileFunctionAttr>())
1002 Fn->addFnAttr(llvm::Attribute::NoProfile);
1004 if (D && D->
hasAttr<HybridPatchableAttr>())
1005 Fn->addFnAttr(llvm::Attribute::HybridPatchable);
1009 if (
auto *A = D->
getAttr<FunctionReturnThunksAttr>()) {
1010 switch (A->getThunkType()) {
1011 case FunctionReturnThunksAttr::Kind::Keep:
1013 case FunctionReturnThunksAttr::Kind::Extern:
1014 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
1017 }
else if (
CGM.getCodeGenOpts().FunctionReturnThunks)
1018 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
1027 EmitKernelMetadata(FD, Fn);
1030 if (FD && FD->
hasAttr<ClspvLibclcBuiltinAttr>()) {
1031 Fn->setMetadata(
"clspv_libclc_builtin",
1038 if (FD &&
SanOpts.has(SanitizerKind::Function) &&
1040 llvm::isCallableCC(Fn->getCallingConv())) {
1042 llvm::LLVMContext &Ctx = Fn->getContext();
1043 llvm::MDBuilder MDB(Ctx);
1045 llvm::LLVMContext::MD_func_sanitize,
1046 MDB.createRTTIPointerPrologue(
1053 if (
SanOpts.has(SanitizerKind::NullabilityReturn)) {
1054 auto Nullability =
FnRetTy->getNullability();
1057 if (!(
SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&
1059 RetValNullabilityPrecondition =
1082 Fn->addFnAttr(llvm::Attribute::NoRecurse);
1085 llvm::fp::ExceptionBehavior FPExceptionBehavior =
1087 Builder.setDefaultConstrainedRounding(RM);
1088 Builder.setDefaultConstrainedExcept(FPExceptionBehavior);
1090 (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
1091 RM != llvm::RoundingMode::NearestTiesToEven))) {
1092 Builder.setIsFPConstrained(
true);
1093 Fn->addFnAttr(llvm::Attribute::StrictFP);
1099 CGM.getCodeGenOpts().StackAlignment))
1100 Fn->addFnAttr(
"stackrealign");
1104 Fn->removeFnAttr(
"zero-call-used-regs");
1107 llvm::StringMap<bool> FeatureMap;
1112 if (T->getAArch64SMEAttributes() &
1119 std::optional<std::pair<unsigned, unsigned>> VScaleRange =
1123 CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
1132 llvm::Value *Poison = llvm::PoisonValue::get(
Int32Ty);
1137 Builder.SetInsertPoint(EntryBB);
1141 if (requiresReturnValueCheck()) {
1152 DI->emitFunctionStart(GD, Loc, StartLoc,
1153 DI->getFunctionType(FD, RetTy, Args),
CurFn,
1158 if (
CGM.getCodeGenOpts().InstrumentFunctions)
1159 CurFn->addFnAttr(
"instrument-function-entry",
"__cyg_profile_func_enter");
1160 if (
CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)
1161 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1162 "__cyg_profile_func_enter");
1163 if (
CGM.getCodeGenOpts().InstrumentFunctionEntryBare)
1164 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1165 "__cyg_profile_func_enter_bare");
1172 if (
CGM.getCodeGenOpts().InstrumentForProfiling) {
1176 if (
CGM.getCodeGenOpts().CallFEntry)
1177 Fn->addFnAttr(
"fentry-call",
"true");
1179 Fn->addFnAttr(
"instrument-function-entry-inlined",
1182 if (
CGM.getCodeGenOpts().MNopMCount) {
1183 if (!
CGM.getCodeGenOpts().CallFEntry)
1184 CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)
1185 <<
"-mnop-mcount" <<
"-mfentry";
1186 Fn->addFnAttr(
"mnop-mcount");
1189 if (
CGM.getCodeGenOpts().RecordMCount) {
1190 if (!
CGM.getCodeGenOpts().CallFEntry)
1191 CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)
1192 <<
"-mrecord-mcount" <<
"-mfentry";
1193 Fn->addFnAttr(
"mrecord-mcount");
1198 if (
CGM.getCodeGenOpts().PackedStack) {
1200 llvm::Triple::systemz)
1201 CGM.getDiags().Report(diag::err_opt_not_valid_on_target)
1202 <<
"-mpacked-stack";
1203 Fn->addFnAttr(
"packed-stack");
1206 if (
CGM.getCodeGenOpts().WarnStackSize !=
UINT_MAX &&
1207 !
CGM.getDiags().isIgnored(diag::warn_fe_backend_frame_larger_than, Loc))
1208 Fn->addFnAttr(
"warn-stack-size",
1209 std::to_string(
CGM.getCodeGenOpts().WarnStackSize));
1221 auto AI =
CurFn->arg_begin();
1222 if (
CurFnInfo->getReturnInfo().isSRetAfterThis())
1225 &*AI, RetTy,
CurFnInfo->getReturnInfo().getIndirectAlign(),
false,
1227 if (!
CurFnInfo->getReturnInfo().getIndirectByVal()) {
1236 unsigned Idx =
CurFnInfo->getReturnInfo().getInAllocaFieldIndex();
1237 llvm::Function::arg_iterator EI =
CurFn->arg_end();
1269 if (FD->
hasAttr<HLSLShaderAttr>()) {
1270 CGM.getHLSLRuntime().emitEntryFunction(FD, Fn);
1276 if (
const CXXMethodDecl *MD = dyn_cast_if_present<CXXMethodDecl>(D);
1281 CGM.getCXXABI().EmitInstanceFunctionProlog(*
this);
1297 CXXThisValue = ThisFieldLValue.
getPointer(*
this);
1306 if (FD->hasCapturedVLAType()) {
1309 auto VAT = FD->getCapturedVLAType();
1310 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
1317 CXXThisValue = CXXABIThisValue;
1321 if (CXXABIThisValue) {
1323 SkippedChecks.
set(SanitizerKind::ObjectSize,
true);
1330 SkippedChecks.
set(SanitizerKind::Null,
true);
1334 Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks);
1341 if (!FD || !FD->
hasAttr<NakedAttr>()) {
1342 for (
const VarDecl *VD : Args) {
1347 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
1348 Ty = PVD->getOriginalType();
1358 DI->EmitLocation(
Builder, StartLoc);
1362 if (
const auto *VecWidth =
CurFuncDecl->getAttr<MinVectorWidthAttr>())
1363 LargestVectorWidth = VecWidth->getVectorWidth();
1365 if (
CGM.shouldEmitConvergenceTokens())
1372 if (
const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
1384 llvm::BasicBlock *SkipCountBB =
nullptr;
1406 if (F->isInterposable())
return;
1408 for (llvm::BasicBlock &BB : *F)
1409 for (llvm::Instruction &I : BB)
1413 F->setDoesNotThrow();
1423 if (
CGM.getCXXABI().HasThisReturn(GD))
1425 else if (
CGM.getCXXABI().hasMostDerivedReturn(GD))
1426 ResTy =
CGM.getContext().VoidPtrTy;
1427 CGM.getCXXABI().buildThisParam(*
this, Args);
1433 bool PassedParams =
true;
1435 if (
auto Inherited = CD->getInheritedConstructor())
1441 Args.push_back(Param);
1442 if (!Param->hasAttr<PassObjectSizeAttr>())
1446 getContext(), Param->getDeclContext(), Param->getLocation(),
1454 CGM.getCXXABI().addImplicitStructorParams(*
this, ResTy, Args);
1461 assert(Fn &&
"generating code for null Function");
1468 CGM.getTargetCodeGenInfo().checkFunctionABI(
CGM, FD);
1474 std::string FDInlineName = (Fn->getName() +
".inline").str();
1475 llvm::Module *M = Fn->getParent();
1476 llvm::Function *Clone = M->getFunction(FDInlineName);
1478 Clone = llvm::Function::Create(Fn->getFunctionType(),
1479 llvm::GlobalValue::InternalLinkage,
1480 Fn->getAddressSpace(), FDInlineName, M);
1481 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
1483 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
1493 if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) {
1494 std::string FDInlineName = (Fn->getName() +
".inline").str();
1495 llvm::Module *M = Fn->getParent();
1496 if (llvm::Function *Clone = M->getFunction(FDInlineName)) {
1497 Clone->replaceAllUsesWith(Fn);
1498 Clone->eraseFromParent();
1506 if (FD->
hasAttr<NoDebugAttr>()) {
1509 Fn->setSubprogram(
nullptr);
1511 DebugInfo =
nullptr;
1514 llvm::scope_exit Cleanup([
this] {
1516 DI->completeFunction();
1523 BodyRange = Body->getSourceRange();
1526 CurEHLocation = BodyRange.getEnd();
1538 if (SpecDecl->hasBody(SpecDecl))
1539 Loc = SpecDecl->getLocation();
1546 ShouldEmitLifetimeMarkers =
true;
1550 if (ShouldEmitLifetimeMarkers)
1555 StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());
1558 if (Body && isa_and_nonnull<CoroutineBodyStmt>(Body))
1566 CurFn->addFnAttr(llvm::Attribute::MustProgress);
1569 PGO->assignRegionCounters(GD,
CurFn);
1576 FD->
hasAttr<CUDAGlobalAttr>())
1577 CGM.getCUDARuntime().emitDeviceStub(*
this, Args);
1600 }
else if (DeviceKernelAttr::isOpenCLSpelling(
1601 FD->
getAttr<DeviceKernelAttr>()) &&
1604 for (
unsigned i = 0; i < Args.size(); ++i) {
1606 QualType ArgQualType = Args[i]->getType();
1608 CallArgs.
add(ArgRValue, ArgQualType);
1612 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FT);
1614 CallArgs, FT,
false);
1615 llvm::FunctionType *FTy =
CGM.getTypes().GetFunctionType(FnInfo);
1616 llvm::Constant *GDStubFunctionPointer =
1617 CGM.getRawFunctionPointer(GDStub, FTy);
1624 llvm_unreachable(
"no definition for emitted function");
1634 bool ShouldEmitUnreachable =
1635 CGM.getCodeGenOpts().StrictReturn ||
1637 if (
SanOpts.has(SanitizerKind::Return)) {
1638 auto CheckOrdinal = SanitizerKind::SO_Return;
1639 auto CheckHandler = SanitizerHandler::MissingReturn;
1641 llvm::Value *IsFalse =
Builder.getFalse();
1642 EmitCheck(std::make_pair(IsFalse, CheckOrdinal), CheckHandler,
1644 }
else if (ShouldEmitUnreachable) {
1645 if (
CGM.getCodeGenOpts().OptimizationLevel == 0)
1648 if (
SanOpts.has(SanitizerKind::Return) || ShouldEmitUnreachable) {
1650 Builder.ClearInsertionPoint();
1657 PGO->verifyCounterMap();
1660 StringRef Identifier =
1661 CurCodeDecl->getAttr<PersonalityAttr>()->getRoutine()->getName();
1662 llvm::FunctionCallee PersonalityRoutine =
1663 CGM.CreateRuntimeFunction(llvm::FunctionType::get(
CGM.Int32Ty,
true),
1664 Identifier, {},
true);
1670 if (!
CurFn->doesNotThrow())
1679 if (!S)
return false;
1696 IgnoreCaseStmts =
true;
1711 if (!S)
return false;
1731 if (!S)
return false;
1762 if (!AllowLabels &&
CGM.getCodeGenOpts().hasProfileClangInstr() &&
1763 CGM.getCodeGenOpts().MCDCCoverage)
1766 llvm::APSInt ResultInt;
1770 ResultBool = ResultInt.getBoolValue();
1778 llvm::APSInt &ResultInt,
1786 llvm::APSInt Int =
Result.Val.getInt();
1790 PGO->markStmtMaybeUsed(
Cond);
1791 ResultInt = std::move(Int);
1820 llvm::BasicBlock *FalseBlock, uint64_t TrueCount ,
1823 bool InstrumentRegions =
CGM.getCodeGenOpts().hasProfileClangInstr();
1827 const Stmt *CntrStmt = (CntrIdx ? CntrIdx :
Cond);
1829 llvm::BasicBlock *ThenBlock =
nullptr;
1830 llvm::BasicBlock *ElseBlock =
nullptr;
1831 llvm::BasicBlock *NextBlock =
nullptr;
1836 llvm::BasicBlock *SkipIncrBlock =
1838 llvm::BasicBlock *SkipNextBlock =
nullptr;
1852 if (LOp == BO_LAnd) {
1853 SkipNextBlock = FalseBlock;
1854 ThenBlock = CounterIncrBlock;
1855 ElseBlock = (SkipIncrBlock ? SkipIncrBlock : SkipNextBlock);
1856 NextBlock = TrueBlock;
1871 else if (LOp == BO_LOr) {
1872 SkipNextBlock = TrueBlock;
1873 ThenBlock = (SkipIncrBlock ? SkipIncrBlock : SkipNextBlock);
1874 ElseBlock = CounterIncrBlock;
1875 NextBlock = FalseBlock;
1877 llvm_unreachable(
"Expected Opcode must be that of a Logical Operator");
1883 if (SkipIncrBlock) {
1907 const Expr *
Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock,
1909 const VarDecl *ConditionalDecl) {
1916 if (CondBOp->getOpcode() == BO_LAnd) {
1919 bool ConstantBool =
false;
1925 FalseBlock, TrueCount, LH);
1935 FalseBlock, TrueCount, LH, CondBOp);
1942 llvm::BasicBlock *LHSFalse =
1970 FalseBlock, TrueCount, LH);
1975 if (CondBOp->getOpcode() == BO_LOr) {
1978 bool ConstantBool =
false;
1984 FalseBlock, TrueCount, LH);
1994 FalseBlock, TrueCount, LH, CondBOp);
1999 llvm::BasicBlock *LHSTrue =
2007 uint64_t RHSCount = TrueCount - LHSCount;
2043 bool MCDCCondition =
CGM.getCodeGenOpts().hasProfileClangInstr() &&
2044 CGM.getCodeGenOpts().MCDCCoverage &&
2046 if (CondUOp->getOpcode() == UO_LNot && !MCDCCondition) {
2073 uint64_t LHSScaledTrueCount = 0;
2077 LHSScaledTrueCount = TrueCount * LHSRatio;
2086 LHSScaledTrueCount, LH, CondOp);
2094 TrueCount - LHSScaledTrueCount, LH, CondOp);
2129 MCDCBaseExpr = ConditionalOp;
2136 llvm::MDNode *Weights =
nullptr;
2137 llvm::MDNode *Unpredictable =
nullptr;
2142 auto *
Call = dyn_cast<CallExpr>(
Cond->IgnoreImpCasts());
2143 if (
Call &&
CGM.getCodeGenOpts().OptimizationLevel != 0) {
2144 auto *FD = dyn_cast_or_null<FunctionDecl>(
Call->getCalleeDecl());
2145 if (FD && FD->
getBuiltinID() == Builtin::BI__builtin_unpredictable) {
2147 Unpredictable = MDHelper.createUnpredictable();
2153 llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH);
2154 if (CondV != NewCondV)
2159 Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);
2162 llvm::Instruction *BrInst =
Builder.CreateCondBr(CondV, TrueBlock, FalseBlock,
2163 Weights, Unpredictable);
2167 case HLSLControlFlowHintAttr::Microsoft_branch:
2168 case HLSLControlFlowHintAttr::Microsoft_flatten: {
2169 llvm::MDBuilder MDHelper(
CGM.getLLVMContext());
2171 llvm::ConstantInt *BranchHintConstant =
2173 HLSLControlFlowHintAttr::Spelling::Microsoft_branch
2174 ? llvm::ConstantInt::get(
CGM.Int32Ty, 1)
2175 : llvm::ConstantInt::get(
CGM.Int32Ty, 2);
2178 {MDHelper.createString(
"hlsl.controlflow.hint"),
2179 MDHelper.createConstant(BranchHintConstant)});
2180 BrInst->setMetadata(
"hlsl.controlflow.hint",
2181 llvm::MDNode::get(
CGM.getLLVMContext(), Vals));
2185 case HLSLControlFlowHintAttr::SpellingNotCalculated:
2193 llvm::Value *Arg =
nullptr;
2194 if ((ICEArguments & (1 << Idx)) == 0) {
2199 std::optional<llvm::APSInt>
Result =
2201 assert(
Result &&
"Expected argument to be a constant");
2210 CGM.ErrorUnsupported(S,
Type);
2222 llvm::Value *sizeInChars) {
2226 llvm::Value *baseSizeInChars
2230 llvm::Value *end = Builder.CreateInBoundsGEP(begin.
getElementType(),
2232 sizeInChars,
"vla.end");
2234 llvm::BasicBlock *originBB = CGF.
Builder.GetInsertBlock();
2242 llvm::PHINode *cur = Builder.CreatePHI(begin.
getType(), 2,
"vla.cur");
2249 Builder.CreateMemCpy(
Address(cur, CGF.
Int8Ty, curAlign), src, baseSizeInChars,
2254 Builder.CreateInBoundsGEP(CGF.
Int8Ty, cur, baseSizeInChars,
"vla.next");
2257 llvm::Value *done = Builder.CreateICmpEQ(next, end,
"vla-init.isdone");
2258 Builder.CreateCondBr(done, contBB, loopBB);
2259 cur->addIncoming(next, loopBB);
2277 if (
CGM.getContext().arePFPFieldsTriviallyCopyable(Field->getParent())) {
2278 uint64_t FieldSignature =
2279 llvm::getPointerAuthStableSipHash(
CGM.getPFPFieldName(Field));
2280 Disc = llvm::ConstantInt::get(
CGM.Int64Ty, FieldSignature);
2284 llvm::GlobalValue *DS =
CGM.getPFPDeactivationSymbol(Field);
2285 llvm::OperandBundleDef DSBundle(
"deactivation-symbol", DS);
2288 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::protected_field_ptr,
2307 llvm::Value *SizeVal;
2314 dyn_cast_or_null<VariableArrayType>(
2317 SizeVal = VlaSize.NumElts;
2319 if (!eltSize.
isOne())
2320 SizeVal =
Builder.CreateNUWMul(SizeVal,
CGM.getSize(eltSize));
2326 SizeVal =
CGM.getSize(size);
2334 if (!
CGM.getTypes().isZeroInitializable(Ty)) {
2338 llvm::Constant *NullConstant =
CGM.EmitNullConstant(Ty);
2340 llvm::GlobalVariable *NullVariable =
2341 new llvm::GlobalVariable(
CGM.getModule(), NullConstant->getType(),
2343 llvm::GlobalVariable::PrivateLinkage,
2344 NullConstant, Twine());
2346 NullVariable->setAlignment(NullAlign.
getAsAlign());
2352 Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal,
false);
2358 Builder.CreateMemSet(DestPtr,
Builder.getInt8(0), SizeVal,
false);
2371 if (!IndirectBranch)
2377 IndirectBranch->addDestination(BB);
2378 return llvm::BlockAddress::get(
CurFn->getType(), BB);
2383 if (IndirectBranch)
return IndirectBranch->getParent();
2388 llvm::Value *DestVal = TmpBuilder.CreatePHI(
Int8PtrTy, 0,
2389 "indirect.goto.dest");
2392 IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
2393 return IndirectBranch->getParent();
2405 llvm::Value *numVLAElements =
nullptr;
2417 baseType = elementType;
2418 return numVLAElements;
2432 llvm::ConstantInt *zero =
Builder.getInt32(0);
2433 gepIndices.push_back(zero);
2435 uint64_t countFromCLAs = 1;
2438 llvm::ArrayType *llvmArrayType =
2440 while (llvmArrayType) {
2443 llvmArrayType->getNumElements());
2445 gepIndices.push_back(zero);
2446 countFromCLAs *= llvmArrayType->getNumElements();
2450 dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
2453 "LLVM and Clang types are out-of-synch");
2472 gepIndices,
"array.begin"),
2478 llvm::Value *numElements
2479 = llvm::ConstantInt::get(
SizeTy, countFromCLAs);
2483 numElements =
Builder.CreateNUWMul(numVLAElements, numElements);
2490 assert(vla &&
"type was not a variable array type!");
2497 llvm::Value *numElements =
nullptr;
2501 elementType =
type->getElementType();
2502 llvm::Value *vlaSize = VLASizeMap[
type->getSizeExpr()];
2503 assert(vlaSize &&
"no size for VLA!");
2504 assert(vlaSize->getType() ==
SizeTy);
2507 numElements = vlaSize;
2511 numElements =
Builder.CreateNUWMul(numElements, vlaSize);
2513 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
2515 return { numElements, elementType };
2521 assert(vla &&
"type was not a variable array type!");
2527 llvm::Value *VlaSize = VLASizeMap[Vla->
getSizeExpr()];
2528 assert(VlaSize &&
"no size for VLA!");
2529 assert(VlaSize->getType() ==
SizeTy);
2534 assert(
type->isVariablyModifiedType() &&
2535 "Must pass variably modified type to EmitVLASizes!");
2542 assert(
type->isVariablyModifiedType());
2544 const Type *ty =
type.getTypePtr();
2547#define TYPE(Class, Base)
2548#define ABSTRACT_TYPE(Class, Base)
2549#define NON_CANONICAL_TYPE(Class, Base)
2550#define DEPENDENT_TYPE(Class, Base) case Type::Class:
2551#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
2552#include "clang/AST/TypeNodes.inc"
2553 llvm_unreachable(
"unexpected dependent type!");
2559 case Type::ExtVector:
2560 case Type::ConstantMatrix:
2564 case Type::TemplateSpecialization:
2565 case Type::ObjCTypeParam:
2566 case Type::ObjCObject:
2567 case Type::ObjCInterface:
2568 case Type::ObjCObjectPointer:
2570 case Type::HLSLInlineSpirv:
2571 case Type::PredefinedSugar:
2572 llvm_unreachable(
"type class is never variably-modified!");
2574 case Type::Adjusted:
2586 case Type::BlockPointer:
2590 case Type::LValueReference:
2591 case Type::RValueReference:
2595 case Type::MemberPointer:
2599 case Type::ArrayParameter:
2600 case Type::ConstantArray:
2601 case Type::IncompleteArray:
2606 case Type::VariableArray: {
2615 llvm::Value *&entry = VLASizeMap[sizeExpr];
2623 if (
SanOpts.has(SanitizerKind::VLABound)) {
2624 auto CheckOrdinal = SanitizerKind::SO_VLABound;
2625 auto CheckHandler = SanitizerHandler::VLABoundNotPositive;
2627 llvm::Value *
Zero = llvm::Constant::getNullValue(size->getType());
2629 llvm::Value *CheckCondition =
2633 llvm::Constant *StaticArgs[] = {
2636 EmitCheck(std::make_pair(CheckCondition, CheckOrdinal),
2637 CheckHandler, StaticArgs, size);
2650 case Type::FunctionProto:
2651 case Type::FunctionNoProto:
2657 case Type::UnaryTransform:
2658 case Type::Attributed:
2659 case Type::BTFTagAttributed:
2660 case Type::OverflowBehavior:
2661 case Type::HLSLAttributedResource:
2662 case Type::SubstTemplateTypeParm:
2663 case Type::MacroQualified:
2664 case Type::CountAttributed:
2670 case Type::Decltype:
2672 case Type::DeducedTemplateSpecialization:
2673 case Type::PackIndexing:
2677 case Type::TypeOfExpr:
2690 }
while (
type->isVariablyModifiedType());
2694 if (
getContext().getBuiltinVaListType()->isArrayType())
2705 assert(
Init.hasValue() &&
"Invalid DeclRefExpr initializer!");
2707 if (
CGM.getCodeGenOpts().hasReducedDebugInfo())
2723 llvm::Instruction *inst =
new llvm::BitCastInst(value, value->getType(),
"",
2727 protection.Inst = inst;
2732 if (!protection.Inst)
return;
2735 protection.Inst->eraseFromParent();
2741 llvm::Value *Alignment,
2742 llvm::Value *OffsetValue) {
2743 if (Alignment->getType() !=
IntPtrTy)
2746 if (OffsetValue && OffsetValue->getType() !=
IntPtrTy)
2749 llvm::Value *TheCheck =
nullptr;
2750 if (
SanOpts.has(SanitizerKind::Alignment)) {
2751 llvm::Value *PtrIntValue =
2755 bool IsOffsetZero =
false;
2756 if (
const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
2757 IsOffsetZero = CI->isZero();
2760 PtrIntValue =
Builder.CreateSub(PtrIntValue, OffsetValue,
"offsetptr");
2763 llvm::Value *
Zero = llvm::ConstantInt::get(
IntPtrTy, 0);
2766 llvm::Value *MaskedPtr =
Builder.CreateAnd(PtrIntValue, Mask,
"maskedptr");
2767 TheCheck =
Builder.CreateICmpEQ(MaskedPtr,
Zero,
"maskcond");
2769 llvm::Instruction *Assumption =
Builder.CreateAlignmentAssumption(
2770 CGM.getDataLayout(), PtrValue, Alignment, OffsetValue);
2772 if (!
SanOpts.has(SanitizerKind::Alignment))
2775 OffsetValue, TheCheck, Assumption);
2781 llvm::Value *Alignment,
2782 llvm::Value *OffsetValue) {
2791 llvm::Value *AnnotatedVal,
2792 StringRef AnnotationStr,
2794 const AnnotateAttr *
Attr) {
2797 CGM.EmitAnnotationString(AnnotationStr),
2798 CGM.EmitAnnotationUnit(Location),
2799 CGM.EmitAnnotationLineNo(Location),
2802 Args.push_back(
CGM.EmitAnnotationArgs(
Attr));
2803 return Builder.CreateCall(AnnotationFn, Args);
2807 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2810 {V->getType(), CGM.ConstGlobalsPtrTy}),
2816 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2817 llvm::Value *
V =
Addr.emitRawPointer(*
this);
2818 llvm::Type *VTy =
V->getType();
2819 auto *PTy = dyn_cast<llvm::PointerType>(VTy);
2820 unsigned AS = PTy ? PTy->getAddressSpace() : 0;
2821 llvm::PointerType *IntrinTy =
2822 llvm::PointerType::get(
CGM.getLLVMContext(), AS);
2823 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
2824 {IntrinTy,
CGM.ConstGlobalsPtrTy});
2830 if (VTy != IntrinTy)
2843 assert(!CGF->IsSanitizerScope);
2844 CGF->IsSanitizerScope =
true;
2848 CGF->IsSanitizerScope =
false;
2852 const llvm::Twine &Name,
2853 llvm::BasicBlock::iterator InsertPt)
const {
2856 I->setNoSanitizeMetadata();
2860 llvm::Instruction *I,
const llvm::Twine &Name,
2861 llvm::BasicBlock::iterator InsertPt)
const {
2862 llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, InsertPt);
2864 CGF->InsertHelper(I, Name, InsertPt);
2873 if (
CGM.getContext().getTargetInfo().getTriple().isX86()) {
2875 if (BuiltinID == X86::BI__builtin_ia32_cmpps ||
2876 BuiltinID == X86::BI__builtin_ia32_cmpss ||
2877 BuiltinID == X86::BI__builtin_ia32_cmppd ||
2878 BuiltinID == X86::BI__builtin_ia32_cmpsd) {
2880 llvm::StringMap<bool> TargetFetureMap;
2881 CGM.getContext().getFunctionFeatureMap(TargetFetureMap, FD);
2883 *(E->
getArg(2)->getIntegerConstantExpr(
CGM.getContext()));
2884 if (
Result.getSExtValue() > 7 && !TargetFetureMap.lookup(
"avx"))
2885 CGM.getDiags().Report(E->
getBeginLoc(), diag::err_builtin_needs_feature)
2906 bool IsAlwaysInline = TargetDecl->
hasAttr<AlwaysInlineAttr>();
2907 bool IsFlatten = FD && FD->
hasAttr<FlattenAttr>();
2913 std::string MissingFeature;
2914 llvm::StringMap<bool> CallerFeatureMap;
2915 CGM.getContext().getFunctionFeatureMap(CallerFeatureMap, FD);
2922 StringRef FeatureList(
CGM.getContext().BuiltinInfo.getRequiredFeatures(BuiltinID));
2924 FeatureList, CallerFeatureMap) && !IsHipStdPar) {
2925 CGM.getDiags().Report(Loc, diag::err_builtin_needs_feature)
2930 TargetDecl->
hasAttr<TargetAttr>()) {
2933 const TargetAttr *TD = TargetDecl->
getAttr<TargetAttr>();
2935 CGM.getContext().filterFunctionTargetAttrs(TD);
2938 llvm::StringMap<bool> CalleeFeatureMap;
2939 CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
2942 if (F[0] ==
'+' && CalleeFeatureMap.lookup(F.substr(1)))
2943 ReqFeatures.push_back(StringRef(F).substr(1));
2946 for (
const auto &F : CalleeFeatureMap) {
2949 ReqFeatures.push_back(F.getKey());
2951 if (!llvm::all_of(ReqFeatures,
2953 if (!CallerFeatureMap.lookup(
Feature)) {
2954 MissingFeature =
Feature.str();
2961 CGM.getDiags().Report(Loc, diag::err_function_needs_feature)
2964 CGM.getDiags().Report(Loc, diag::err_flatten_function_needs_feature)
2969 llvm::StringMap<bool> CalleeFeatureMap;
2970 CGM.getContext().getFunctionFeatureMap(CalleeFeatureMap, TargetDecl);
2972 for (
const auto &F : CalleeFeatureMap) {
2974 (!CallerFeatureMap.lookup(F.getKey()) ||
2975 !CallerFeatureMap.find(F.getKey())->getValue()) &&
2978 CGM.getDiags().Report(Loc, diag::err_function_needs_feature)
2981 CGM.getDiags().Report(Loc, diag::err_flatten_function_needs_feature)
2989 if (!
CGM.getCodeGenOpts().SanitizeStats)
2992 llvm::IRBuilder<> IRB(
Builder.GetInsertBlock(),
Builder.GetInsertPoint());
2993 IRB.SetCurrentDebugLocation(
Builder.getCurrentDebugLocation());
2994 CGM.getSanStats().create(IRB, SSK);
3006 Salt = Info.CFISalt;
3008 Bundles.emplace_back(
"kcfi",
CGM.CreateKCFITypeId(FP->
desugar(), Salt));
3012CodeGenFunction::FormAArch64ResolverCondition(
const FMVResolverOption &RO) {
3013 return RO.Features.empty() ?
nullptr : EmitAArch64CpuSupports(RO.Features);
3017CodeGenFunction::FormX86ResolverCondition(
const FMVResolverOption &RO) {
3020 if (RO.Architecture) {
3021 StringRef
Arch = *RO.Architecture;
3024 if (
Arch.starts_with(
"x86-64"))
3030 if (!RO.Features.empty()) {
3031 llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Features);
3039 llvm::Function *Resolver,
3041 llvm::Function *FuncToReturn,
3042 bool SupportsIFunc) {
3043 if (SupportsIFunc) {
3044 Builder.CreateRet(FuncToReturn);
3049 llvm::make_pointer_range(Resolver->args()));
3051 llvm::CallInst *Result = Builder.CreateCall(FuncToReturn, Args);
3052 Result->setTailCallKind(llvm::CallInst::TCK_MustTail);
3054 if (Resolver->getReturnType()->isVoidTy())
3055 Builder.CreateRetVoid();
3057 Builder.CreateRet(Result);
3063 llvm::Triple::ArchType ArchType =
3067 case llvm::Triple::x86:
3068 case llvm::Triple::x86_64:
3071 case llvm::Triple::aarch64:
3074 case llvm::Triple::riscv32:
3075 case llvm::Triple::riscv64:
3076 case llvm::Triple::riscv32be:
3077 case llvm::Triple::riscv64be:
3080 case llvm::Triple::ppc:
3081 case llvm::Triple::ppc64:
3089 "Only implemented for x86, AArch64, RISC-V, and PowerPC AIX");
3117 Builder.SetInsertPoint(CurBlock);
3119 if (!RO.Architecture && RO.Features.empty()) {
3122 assert(&RO == Options.end() - 1 &&
3123 "Default or Generic case must be last");
3124 Builder.CreateRet(RO.Function);
3133 assert(RO.Features.size() == 1 &&
3134 "for now one feature requirement per version");
3136 assert(RO.Features[0].starts_with(
"cpu="));
3137 StringRef CPU = RO.Features[0].split(
"=").second.trim();
3138 StringRef
Feature = llvm::StringSwitch<StringRef>(CPU)
3139 .Case(
"pwr7",
"arch_2_06")
3140 .Case(
"pwr8",
"arch_2_07")
3141 .Case(
"pwr9",
"arch_3_00")
3142 .Case(
"pwr10",
"arch_3_1")
3143 .Case(
"pwr11",
"arch_3_1")
3147 Builtin::BI__builtin_cpu_supports,
Builder.getInt1Ty(),
Feature);
3153 Builder.SetInsertPoint(ThenBlock);
3154 Builder.CreateRet(RO.Function);
3157 llvm_unreachable(
"Default case missing");
3164 llvm::Triple::OSType::Linux) {
3165 CGM.getDiags().Report(diag::err_os_unsupport_riscv_fmv);
3170 Builder.SetInsertPoint(CurBlock);
3174 bool HasDefault =
false;
3175 unsigned DefaultIndex = 0;
3178 for (
unsigned Index = 0; Index < Options.size(); Index++) {
3180 if (Options[Index].Features.empty()) {
3182 DefaultIndex = Index;
3186 Builder.SetInsertPoint(CurBlock);
3212 for (StringRef Feat : Options[Index].Features) {
3213 std::vector<std::string> FeatStr =
3216 assert(FeatStr.size() == 1 &&
"Feature string not delimited");
3218 std::string &CurrFeat = FeatStr.front();
3219 if (CurrFeat[0] ==
'+')
3220 TargetAttrFeats.push_back(CurrFeat.substr(1));
3223 if (TargetAttrFeats.empty())
3226 for (std::string &Feat : TargetAttrFeats)
3227 CurrTargetAttrFeats.push_back(Feat);
3229 Builder.SetInsertPoint(CurBlock);
3232 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
3235 Options[Index].
Function, SupportsIFunc);
3238 Builder.SetInsertPoint(CurBlock);
3239 Builder.CreateCondBr(FeatsCondition, RetBlock, ElseBlock);
3241 CurBlock = ElseBlock;
3246 Builder.SetInsertPoint(CurBlock);
3253 Builder.SetInsertPoint(CurBlock);
3254 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
3255 TrapCall->setDoesNotReturn();
3256 TrapCall->setDoesNotThrow();
3258 Builder.ClearInsertionPoint();
3263 assert(!Options.empty() &&
"No multiversion resolver options found");
3264 assert(Options.back().Features.size() == 0 &&
"Default case must be last");
3266 assert(SupportsIFunc &&
3267 "Multiversion resolver requires target IFUNC support");
3268 bool AArch64CpuInitialized =
false;
3272 Builder.SetInsertPoint(CurBlock);
3273 llvm::Value *
Condition = FormAArch64ResolverCondition(RO);
3282 if (!AArch64CpuInitialized) {
3283 Builder.SetInsertPoint(CurBlock, CurBlock->begin());
3284 EmitAArch64CpuInit();
3285 AArch64CpuInitialized =
true;
3286 Builder.SetInsertPoint(CurBlock);
3290 if (RO.Function ==
nullptr)
3293 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
3302 Builder.SetInsertPoint(CurBlock);
3303 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
3304 TrapCall->setDoesNotReturn();
3305 TrapCall->setDoesNotThrow();
3307 Builder.ClearInsertionPoint();
3317 Builder.SetInsertPoint(CurBlock);
3321 Builder.SetInsertPoint(CurBlock);
3322 llvm::Value *
Condition = FormX86ResolverCondition(RO);
3326 assert(&RO == Options.end() - 1 &&
3327 "Default or Generic case must be last");
3333 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
3342 Builder.SetInsertPoint(CurBlock);
3343 llvm::CallInst *TrapCall =
EmitTrapCall(llvm::Intrinsic::trap);
3344 TrapCall->setDoesNotReturn();
3345 TrapCall->setDoesNotThrow();
3347 Builder.ClearInsertionPoint();
3359 llvm::Value *OffsetValue, llvm::Value *TheCheck,
3360 llvm::Instruction *Assumption) {
3361 assert(isa_and_nonnull<llvm::CallInst>(Assumption) &&
3363 llvm::Intrinsic::getOrInsertDeclaration(
3364 Builder.GetInsertBlock()->getParent()->getParent(),
3365 llvm::Intrinsic::assume) &&
3366 "Assumption should be a call to llvm.assume().");
3367 assert(&(
Builder.GetInsertBlock()->back()) == Assumption &&
3368 "Assumption should be the last instruction of the basic block, "
3369 "since the basic block is still being generated.");
3371 if (!
SanOpts.has(SanitizerKind::Alignment))
3381 Assumption->removeFromParent();
3384 auto CheckOrdinal = SanitizerKind::SO_Alignment;
3385 auto CheckHandler = SanitizerHandler::AlignmentAssumption;
3389 OffsetValue =
Builder.getInt1(
false);
3394 llvm::Value *DynamicData[] = {Ptr, Alignment, OffsetValue};
3395 EmitCheck({std::make_pair(TheCheck, CheckOrdinal)}, CheckHandler,
3396 StaticData, DynamicData);
3407 return DI->SourceLocToDebugLoc(Location);
3409 return llvm::DebugLoc();
3413CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *
Cond,
3424 llvm::Type *CondTy =
Cond->getType();
3425 assert(CondTy->isIntegerTy(1) &&
"expecting condition to be a boolean");
3426 llvm::Function *FnExpect =
3428 llvm::Value *ExpectedValueOfCond =
3430 return Builder.CreateCall(FnExpect, {
Cond, ExpectedValueOfCond},
3431 Cond->getName() +
".expval");
3433 llvm_unreachable(
"Unknown Likelihood");
3437 unsigned NumElementsDst,
3438 const llvm::Twine &Name) {
3440 unsigned NumElementsSrc = SrcTy->getNumElements();
3441 if (NumElementsSrc == NumElementsDst)
3444 std::vector<int> ShuffleMask(NumElementsDst, -1);
3445 for (
unsigned MaskIdx = 0;
3446 MaskIdx < std::min<>(NumElementsDst, NumElementsSrc); ++MaskIdx)
3447 ShuffleMask[MaskIdx] = MaskIdx;
3449 return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name);
3462 Discriminator =
Builder.getSize(0);
3464 llvm::Value *Args[] = {Key, Discriminator};
3465 Bundles.emplace_back(
"ptrauth", Args);
3471 unsigned IntrinsicID) {
3478 if (!Discriminator) {
3483 auto OrigType =
Pointer->getType();
3501 llvm::Intrinsic::ptrauth_sign);
3507 auto StripIntrinsic = CGF.
CGM.
getIntrinsic(llvm::Intrinsic::ptrauth_strip);
3511 auto OrigType =
Pointer->getType();
3528 llvm::Intrinsic::ptrauth_auth);
3532 llvm::Instruction *KeyInstruction, llvm::Value *Backup) {
3534 DI->addInstToCurrentSourceAtom(KeyInstruction, Backup);
3538 llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom) {
3540 DI->addInstToSpecificSourceAtom(KeyInstruction, Backup, Atom);
3544 llvm::Value *Backup) {
3547 DI->addInstToCurrentSourceAtom(KeyInstruction, Backup);
3554 if (
getContext().arePFPFieldsTriviallyCopyable(Field.Field->getParent()))
3558 Builder.CreateStore(
Builder.CreateLoad(SrcFieldPtr), DestFieldPtr);
static void findPFPFields(const ASTContext &Ctx, QualType Ty, CharUnits Offset, std::vector< PFPField > &Fields, bool IncludeVBases)
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines enum values for all the target-independent builtin functions.
static llvm::Value * EmitPointerAuthCommon(CodeGenFunction &CGF, const CGPointerAuthInfo &PointerAuth, llvm::Value *Pointer, unsigned IntrinsicID)
static void CreateMultiVersionResolverReturn(CodeGenModule &CGM, llvm::Function *Resolver, CGBuilderTy &Builder, llvm::Function *FuncToReturn, bool SupportsIFunc)
static llvm::Value * EmitStrip(CodeGenFunction &CGF, const CGPointerAuthInfo &PointerAuth, llvm::Value *Pointer)
static void emitNonZeroVLAInit(CodeGenFunction &CGF, QualType baseType, Address dest, Address src, llvm::Value *sizeInChars)
emitNonZeroVLAInit - Emit the "zero" initialization of a variable-length array whose elements have a ...
static void EmitIfUsed(CodeGenFunction &CGF, llvm::BasicBlock *BB)
static LValue makeNaturalAlignAddrLValue(llvm::Value *V, QualType T, bool ForPointeeType, bool MightBeSigned, CodeGenFunction &CGF, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
static void TryMarkNoThrow(llvm::Function *F)
Tries to mark the given function nounwind based on the non-existence of any throwing calls within it.
static llvm::Constant * getPrologueSignature(CodeGenModule &CGM, const FunctionDecl *FD)
Return the UBSan prologue signature for FD if one is available.
static bool endsWithReturn(const Decl *F)
Determine whether the function F ends with a return stmt.
static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, const LangOptions &LangOpts)
shouldEmitLifetimeMarkers - Decide whether we need emit the life-time markers.
static bool matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static StringRef getTriple(const Command &Job)
Defines the Objective-C statement AST node classes.
Enumerates target-specific builtins in their own namespaces within namespace clang.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
bool hasAnyFunctionEffects() const
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.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
const VariableArrayType * getAsVariableArrayType(QualType T) const
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
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)
BinaryOperatorKind Opcode
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.
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
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
A C++ throw-expression (C++ [except.throw]).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
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...
@ 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...
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * getBasePointer() const
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::PointerType * getType() const
Return the type of the pointer value.
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
A scoped helper to set the current debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const override
This forwards to CodeGenFunction::InsertHelper.
llvm::ConstantInt * getSize(CharUnits N)
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
Abstract information about a function or function prototype.
const FunctionProtoType * getCalleeFunctionProtoType() const
All available information about a concrete callee.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
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.
bool isDelegateCall() const
llvm::Value * getDiscriminator() const
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
virtual ~CGCapturedStmtInfo()
CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures)
An object to manage conditionally-evaluated expressions.
void begin(CodeGenFunction &CGF)
void end(CodeGenFunction &CGF)
An object which temporarily prevents a value from being destroyed by aggressive peephole optimization...
SanitizerScope(CodeGenFunction *CGF)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitRISCVMultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr, const VarDecl *ConditionalDecl=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
void setCurrentProfileCount(uint64_t Count)
Set the profiler's current count.
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
void EmitAArch64MultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
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...
llvm::Value * EmitScalarOrConstFoldImmArg(unsigned ICEArguments, unsigned Idx, const CallExpr *E)
SanitizerSet SanOpts
Sanitizers enabled for this function.
@ UseSkipPath
Skip (false)
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl)
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
void EmitPPCAIXMultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
define internal ptr @foo.resolver() { entry: is_version_1 = __builtin_cpu_supports(version_1) br i1 %...
bool ShouldSkipSanitizerInstrumentation()
ShouldSkipSanitizerInstrumentation - Return true if the current function should not be instrumented w...
llvm::Value * EmitPPCBuiltinCpu(unsigned BuiltinID, llvm::Type *ReturnType, StringRef CPUStr)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
llvm::Value * EmitRISCVCpuSupports(const CallExpr *E)
llvm::Value * EmitRISCVCpuInit()
static bool hasScalarEvaluationKind(QualType T)
llvm::Type * ConvertType(QualType T)
void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo)
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)
void addInstToNewSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
Add KeyInstruction and an optional Backup instruction to a new atom group (See ApplyAtomGroup for mor...
FieldDecl * LambdaThisCaptureField
PeepholeProtection protectFromPeepholes(RValue rvalue)
protectFromPeepholes - Protect a value that we're intending to store to the side, but which will prob...
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T)
Given a value of type T* that may not be to a complete object, construct an l-value with the natural ...
JumpDest getJumpDestForLabel(const LabelDecl *S)
getBasicBlockForLabel - Return the LLVM basicblock that the specified label maps to.
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack
Stack to track the controlled convergence tokens.
void unprotectFromPeepholes(PeepholeProtection protection)
RValue convertTempToRValue(Address addr, QualType type, SourceLocation Loc)
Given the address of a temporary variable, produce an r-value of its type.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
const LangOptions & getLangOpts() const
void addInstToSpecificSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom)
See CGDebugInfo::addInstToSpecificSourceAtom.
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
void EmitVarAnnotations(const VarDecl *D, llvm::Value *V)
Emit local annotations for the local variable V, declared by D.
llvm::BasicBlock * EHResumeBlock
EHResumeBlock - Unified block containing a call to llvm.eh.resume.
Address EmitFieldAnnotations(const FieldDecl *D, Address V)
Emit field annotations for the given field & value.
void EmitConstructorBody(FunctionArgList &Args)
EmitConstructorBody - Emits the body of the current constructor.
void EmitKCFIOperandBundle(const CGCallee &Callee, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
void EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init)
Address makeNaturalAddressForPointer(llvm::Value *Ptr, QualType T, CharUnits Alignment=CharUnits::Zero(), bool ForPointeeType=false, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
Construct an address with the natural alignment of T.
LValue MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T)
Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known to be unsigned.
@ 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.
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
bool hasSkipCounter(const Stmt *S) const
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
void EmitFunctionBody(const Stmt *Body)
JumpDest ReturnBlock
ReturnBlock - Unified return block.
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)
Converts Location to a DebugLoc, if debug information is enabled.
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
llvm::DebugLoc EmitReturnBlock()
Emit the unified return block, trying to avoid its emission when possible.
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
const TargetInfo & getTarget() const
llvm::Value * EmitAnnotationCall(llvm::Function *AnnotationFn, llvm::Value *AnnotatedVal, StringRef AnnotationStr, SourceLocation Location, const AnnotateAttr *Attr)
Emit an annotation call (intrinsic).
Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
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.
void maybeCreateMCDCCondBitmap()
Allocate a temp value on the stack that MCDC can use to track condition results.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
RawAddress CreateIRTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateIRTempWithoutCast - Create a temporary IR object of the given type, with appropriate alignment.
bool AlwaysEmitXRayCustomEvents() const
AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit XRay custom event handling c...
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.
llvm::Value * EmitPointerAuthSign(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn)
Annotate the function with an attribute that disables TSan checking at runtime.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
void EmitPointerAuthOperandBundle(const CGPointerAuthInfo &Info, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs, const TrapReason *TR=nullptr)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const
CGBuilder insert helper.
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...
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
bool AlwaysEmitXRayTypedEvents() const
AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit XRay typed event handling ...
CGDebugInfo * getDebugInfo()
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
void EmitDestructorBody(FunctionArgList &Args)
EmitDestructorBody - Emits the body of the current destructor.
void EmitX86MultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
bool ShouldInstrumentFunction()
ShouldInstrumentFunction - Return true if the current function should be instrumented with __cyg_prof...
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue, llvm::Value *TheCheck, llvm::Instruction *Assumption)
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
llvm::ConstantInt * getUBSanFunctionTypeHash(QualType T) const
Return a type hash constant for a function instrumented by -fsanitize=function.
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...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
ASTContext & getContext() const
bool isMCDCBranchExpr(const Expr *E) const
void EmitMultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
static const Expr * stripCond(const Expr *C)
Ignore parentheses and logical-NOT to track conditions consistently.
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 EmitAddressOfPFPField(Address RecordPtr, const PFPField &Field)
void SetFastMathFlags(FPOptions FPFeatures)
Set the codegen fast-math flags.
llvm::SmallVector< char, 256 > LifetimeExtendedCleanupStack
Address EmitVAListRef(const Expr *E)
void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD)
Address ReturnValuePointer
ReturnValuePointer - The temporary alloca to hold a pointer to sret.
static bool mightAddDeclToScope(const Stmt *S)
Determine if the given statement might introduce a declaration into the current scope,...
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
uint64_t getCurrentProfileCount()
Get the profiler's current count.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitEndEHSpec(const Decl *D)
EmitEndEHSpec - Emit the end of the exception spec.
LValue EmitLValueForLambdaField(const FieldDecl *Field)
void emitPFPPostCopyUpdates(Address DestPtr, Address SrcPtr, QualType Ty)
Copy all PFP fields from SrcPtr to DestPtr while updating signatures, assuming that DestPtr was alrea...
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
static bool containsBreak(const Stmt *S)
containsBreak - Return true if the statement contains a break out of it.
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
HLSLControlFlowHintAttr::Spelling HLSLControlFlowAttr
HLSL Branch attribute.
void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, LValue LV, QualType Type, SanitizerSet SkippedChecks=SanitizerSet(), llvm::Value *ArraySize=nullptr)
llvm::SmallVector< const ParmVarDecl *, 4 > FnArgs
Save Parameter Decl for coroutine.
const TargetInfo & Target
void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc, uint64_t RetKeyInstructionsSourceAtom)
EmitFunctionEpilog - Emit the target specific LLVM code to return the given temporary.
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 EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
RawAddress NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
VarBypassDetector Bypasses
llvm::BasicBlock * GetIndirectGotoBlock()
EHScopeStack::stable_iterator PrologueCleanupDepth
PrologueCleanupDepth - The cleanup depth enclosing all the cleanups associated with the parameters.
Address EmitMSVAListRef(const Expr *E)
Emit a "reference" to a __builtin_ms_va_list; this is always the value of the expression,...
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
const CGFunctionInfo * CurFnInfo
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
bool ShouldXRayInstrumentFunction() const
ShouldXRayInstrument - Return true if the current function should be instrumented with XRay nop sleds...
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
llvm::LLVMContext & getLLVMContext()
bool SawAsmBlock
Whether we processed a Microsoft-style asm block during CodeGen.
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.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
bool isMCDCDecisionExpr(const Expr *E) const
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
void MaybeEmitDeferredVarDeclInit(const VarDecl *var)
void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S)
When instrumenting to collect profile data, the counts for some blocks such as switch cases need to n...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
This class organizes the cross-function state that is used while generating LLVM code.
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
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::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
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...
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
llvm::Value * getPointer(CodeGenFunction &CGF) const
Address getAddress() const
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.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
virtual llvm::Constant * getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const
Return a constant used by UBSan as a signature to identify functions possessing type information,...
CompoundStmt - This represents a group of statements like { stmt stmt }.
ConditionalOperator - The ?
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
This represents one expression.
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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...
FunctionEffectsRef getFunctionEffects() const
bool isMSVCRTEntryPoint() const
Determines whether this function is a MSVCRT user defined entry point.
bool isInlineBuiltinDeclaration() const
Determine if this function provides an inline implementation of a builtin.
bool hasImplicitReturnZero() const
Whether falling off this function implicitly returns null/zero.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program.
bool isDefaulted() const
Whether this function is defaulted.
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
FunctionDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Represents a prototype with parameter type info, e.g.
FunctionTypeExtraAttributeInfo getExtraAttributeInfo() const
Return the extra attribute information.
FunctionType - C99 6.7.5.3 - Function Declarators.
@ SME_PStateSMCompatibleMask
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
KernelReferenceKind getKernelReferenceKind() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Represents the declaration of a label.
FPExceptionModeKind
Possible floating point exception behavior.
@ FPE_Strict
Strictly preserve the floating-point exception semantics.
@ FPE_MayTrap
Transformations do not cause new exceptions but may hide some.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
SanitizerSet Sanitize
Set of enabled sanitizers.
RoundingMode getDefaultRoundingMode() const
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
Encodes a location in the source.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
StmtClass getStmtClass() const
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.
virtual std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts, ArmStreamingKind Mode, llvm::StringMap< bool > *FeatureMap=nullptr) const
Returns target-specific min and max values VScale_Range.
bool supportsIFunc() const
Identify whether this target supports IFuncs.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
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
bool isFunctionNoProtoType() const
bool isCFIUncheckedCalleeFunctionType() 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.
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
CGBuilderInserter CGBuilderInserterTy
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
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Expr * IgnoreBuiltinExpectSingleStep(Expr *E)
@ NonNull
Values of this type can never be null.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
Expr * IgnoreImplicitCastsSingleStep(Expr *E)
Expr * IgnoreUOpLNotSingleStep(Expr *E)
Expr * IgnoreParensSingleStep(Expr *E)
llvm::fp::ExceptionBehavior ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind)
U cast(CodeGen::Address addr)
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
@ Other
Other implicit parameter.
@ EST_None
no exception specification
@ Implicit
An implicit conversion.
A jump destination is an abstract label, branching to which may require a jump out through normal cle...
llvm::BasicBlock * getBlock() const
This structure provides a set of types that are commonly used during IR emission.
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
EvalResult is a struct with detailed info about an evaluated expression.
A FunctionEffect plus a potential boolean expression determining whether the effect is declared (e....
Contains information gathered from parsing the contents of TargetAttr.
std::vector< std::string > Features
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.