40#include "llvm/ADT/ArrayRef.h"
41#include "llvm/ADT/ScopeExit.h"
42#include "llvm/ADT/StringExtras.h"
43#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
44#include "llvm/IR/DataLayout.h"
45#include "llvm/IR/Dominators.h"
46#include "llvm/IR/FPEnv.h"
47#include "llvm/IR/Instruction.h"
48#include "llvm/IR/IntrinsicInst.h"
49#include "llvm/IR/Intrinsics.h"
50#include "llvm/IR/IntrinsicsPowerPC.h"
51#include "llvm/IR/MDBuilder.h"
52#include "llvm/Support/CRC.h"
53#include "llvm/Support/SaveAndRestore.h"
54#include "llvm/Support/SipHash.h"
55#include "llvm/Support/xxhash.h"
56#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
57#include "llvm/Transforms/Utils/PromoteMemToReg.h"
63CodeGenFunction::CodeGenFunction(
CodeGenModule &cgm,
bool suppressNewContext)
67 DebugInfo(
CGM.getModuleDebugInfo()),
69 ShouldEmitLifetimeMarkers(
CodeGenUtils::shouldEmitLifetimeMarkers(
71 if (!suppressNewContext)
72 CGM.getCXXABI().getMangleContext().startNewFunction();
79 const auto *FD = dyn_cast_or_null<FunctionDecl>(
CurCodeDecl);
88 "missed to deactivate a cleanup");
91 CGM.getOpenMPRuntime().functionFinished(*
this);
98 if (
CGM.getLangOpts().OpenMPIRBuilder &&
CurFn)
99 CGM.getOpenMPRuntime().getOMPBuilder().finalize(
CurFn);
104llvm::fp::ExceptionBehavior
112 llvm_unreachable(
"Unsupported FP Exception Behavior");
117 llvm::FastMathFlags FMF;
118 FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
119 FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
120 FMF.setNoInfs(FPFeatures.getNoHonorInfs());
121 FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
122 FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
123 FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
137 ConstructorHelper(FPFeatures);
140void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(
FPOptions FPFeatures) {
141 OldFPFeatures = CGF.CurFPFeatures;
142 CGF.CurFPFeatures = FPFeatures;
144 OldExcept = CGF.Builder.getDefaultConstrainedExcept();
145 OldRounding = CGF.Builder.getDefaultConstrainedRounding();
147 if (OldFPFeatures == FPFeatures)
150 FMFGuard.emplace(CGF.Builder);
153 CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
154 auto NewExceptionBehavior =
156 CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
158 CGF.SetFastMathFlags(FPFeatures);
160 assert((CGF.CurFuncDecl ==
nullptr || CGF.Builder.getIsFPConstrained() ||
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-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
178 CGF.CurFPFeatures = OldFPFeatures;
179 CGF.Builder.setDefaultConstrainedExcept(OldExcept);
180 CGF.Builder.setDefaultConstrainedRounding(OldRounding);
194 nullptr, IsKnownNonNull)
202 return ::makeNaturalAlignAddrLValue(
V,
T,
false,
209 return ::makeNaturalAlignAddrLValue(
V,
T,
true,
215 return ::makeNaturalAlignAddrLValue(
V,
T,
false,
221 return ::makeNaturalAlignAddrLValue(
V,
T,
true,
226 return CGM.getTypes().ConvertTypeForMem(
T);
230 return CGM.getTypes().ConvertType(
T);
234 llvm::Type *LLVMTy) {
235 return CGM.getTypes().convertTypeForLoadStore(ASTTy, LLVMTy);
241 switch (
type->getTypeClass()) {
242#define TYPE(name, parent)
243#define ABSTRACT_TYPE(name, parent)
244#define NON_CANONICAL_TYPE(name, parent) case Type::name:
245#define DEPENDENT_TYPE(name, parent) case Type::name:
246#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type::name:
247#include "clang/AST/TypeNodes.inc"
248 llvm_unreachable(
"non-canonical or dependent type in IR-generation");
251 case Type::DeducedTemplateSpecialization:
252 llvm_unreachable(
"undeduced type in IR-generation");
257 case Type::BlockPointer:
258 case Type::LValueReference:
259 case Type::RValueReference:
260 case Type::MemberPointer:
262 case Type::ExtVector:
263 case Type::ConstantMatrix:
264 case Type::FunctionProto:
265 case Type::FunctionNoProto:
267 case Type::ObjCObjectPointer:
270 case Type::HLSLAttributedResource:
271 case Type::HLSLInlineSpirv:
272 case Type::OverflowBehavior:
280 case Type::ConstantArray:
281 case Type::IncompleteArray:
282 case Type::VariableArray:
284 case Type::ObjCObject:
285 case Type::ObjCInterface:
286 case Type::ArrayParameter:
294 llvm_unreachable(
"unknown type kind!");
301 llvm::BasicBlock *CurBB =
Builder.GetInsertBlock();
304 assert(!CurBB->hasTerminator() &&
"Unexpected terminated block.");
308 if (CurBB->empty() ||
ReturnBlock.getBlock()->use_empty()) {
314 return llvm::DebugLoc();
322 dyn_cast<llvm::UncondBrInst>(*
ReturnBlock.getBlock()->user_begin());
323 if (BI && BI->getSuccessor(0) ==
ReturnBlock.getBlock()) {
326 llvm::DebugLoc Loc = BI->getDebugLoc();
327 Builder.SetInsertPoint(BI->getParent());
328 BI->eraseFromParent();
340 return llvm::DebugLoc();
345 if (!BB->use_empty()) {
353 assert(BreakContinueStack.empty() &&
354 "mismatched push/pop in break/continue stack!");
356 "mismatched push/pop of cleanups in EHStack!");
358 "mismatched activate/deactivate of cleanups!");
360 if (
CGM.shouldEmitConvergenceTokens()) {
363 "mismatched push/pop in convergence stack!");
366 bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
367 && NumSimpleReturnExprs == NumReturnExprs
382 if (OnlySimpleReturnStmts)
383 DI->EmitLocation(
Builder, LastStopPoint);
385 DI->EmitLocation(
Builder, EndLoc);
393 bool HasOnlyNoopCleanups =
395 bool EmitRetDbgLoc = !HasCleanups || HasOnlyNoopCleanups;
397 std::optional<ApplyDebugLocation> OAL;
402 if (OnlySimpleReturnStmts)
403 DI->EmitLocation(
Builder, EndLoc);
417 if (
CGM.getCodeGenOpts().InstrumentFunctions)
418 CurFn->addFnAttr(
"instrument-function-exit",
"__cyg_profile_func_exit");
419 if (
CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)
420 CurFn->addFnAttr(
"instrument-function-exit-inlined",
421 "__cyg_profile_func_exit");
430 uint64_t RetKeyInstructionsAtomGroup = Loc ? Loc->getAtomGroup() : 0;
433 RetKeyInstructionsAtomGroup);
437 "did not remove all scopes from cleanup stack!");
441 if (IndirectBranch) {
448 if (!EscapedLocals.empty()) {
452 EscapeArgs.resize(EscapedLocals.size());
453 for (
auto &Pair : EscapedLocals)
454 EscapeArgs[Pair.second] = Pair.first;
455 llvm::Function *FrameEscapeFn = llvm::Intrinsic::getOrInsertDeclaration(
456 &
CGM.getModule(), llvm::Intrinsic::localescape);
463 Ptr->eraseFromParent();
467 if (PostAllocaInsertPt) {
468 llvm::Instruction *PostPtr = PostAllocaInsertPt;
469 PostAllocaInsertPt =
nullptr;
470 PostPtr->eraseFromParent();
475 if (IndirectBranch) {
477 if (PN->getNumIncomingValues() == 0) {
478 PN->replaceAllUsesWith(llvm::PoisonValue::get(PN->getType()));
479 PN->eraseFromParent();
488 for (
const auto &FuncletAndParent : TerminateFunclets)
491 if (
CGM.getCodeGenOpts().EmitDeclMetadata)
494 for (
const auto &R : DeferredReplacements) {
495 if (llvm::Value *Old = R.first) {
496 Old->replaceAllUsesWith(R.second);
500 DeferredReplacements.clear();
509 llvm::DominatorTree DT(*
CurFn);
510 llvm::PromoteMemToReg(
516 for (llvm::Argument &A :
CurFn->args())
517 if (
auto *VT = dyn_cast<llvm::VectorType>(A.getType()))
519 std::max((uint64_t)LargestVectorWidth,
520 VT->getPrimitiveSizeInBits().getKnownMinValue());
523 if (
auto *VT = dyn_cast<llvm::VectorType>(
CurFn->getReturnType()))
525 std::max((uint64_t)LargestVectorWidth,
526 VT->getPrimitiveSizeInBits().getKnownMinValue());
528 if (
CurFnInfo->getMaxVectorWidth() > LargestVectorWidth)
529 LargestVectorWidth =
CurFnInfo->getMaxVectorWidth();
539 CurFn->addFnAttr(
"min-legal-vector-width",
540 llvm::utostr(LargestVectorWidth));
549 dyn_cast<llvm::AllocaInst>(
ReturnValue.emitRawPointer(*
this));
550 if (RetAlloca && RetAlloca->use_empty()) {
551 RetAlloca->eraseFromParent();
560 if (!
CGM.getCodeGenOpts().InstrumentFunctions &&
561 !
CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining &&
562 !
CGM.getCodeGenOpts().InstrumentFunctionEntryBare)
572 return CurFuncDecl->hasAttr<DisableSanitizerInstrumentationAttr>();
578 return CGM.getCodeGenOpts().XRayInstrumentFunctions;
584 return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
585 (
CGM.getCodeGenOpts().XRayAlwaysEmitCustomEvents ||
586 CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
591 return CGM.getCodeGenOpts().XRayInstrumentFunctions &&
592 (
CGM.getCodeGenOpts().XRayAlwaysEmitTypedEvents ||
593 CGM.getCodeGenOpts().XRayInstrumentationBundle.Mask ==
604 llvm::raw_string_ostream Out(Mangled);
605 CGM.getCXXABI().getMangleContext().mangleCanonicalTypeName(Ty, Out,
false);
606 return llvm::ConstantInt::get(
607 CGM.Int32Ty,
static_cast<uint32_t
>(llvm::xxh3_64bits(Mangled)));
610void CodeGenFunction::EmitKernelMetadata(
const FunctionDecl *FD,
611 llvm::Function *Fn) {
612 if (!FD->
hasAttr<DeviceKernelAttr>() && !FD->
hasAttr<CUDAGlobalAttr>())
624 if (
const VecTypeHintAttr *A = FD->
getAttr<VecTypeHintAttr>()) {
625 QualType HintQTy = A->getTypeHint();
627 bool IsSignedInteger =
629 (HintEltQTy && HintEltQTy->
getElementType()->isSignedIntegerType());
630 llvm::Metadata *AttrMDArgs[] = {
631 llvm::ConstantAsMetadata::get(llvm::PoisonValue::get(
633 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
634 llvm::IntegerType::get(Context, 32),
635 llvm::APInt(32, (uint64_t)(IsSignedInteger ? 1 : 0))))};
636 Fn->setMetadata(
"vec_type_hint", llvm::MDNode::get(Context, AttrMDArgs));
639 if (
const WorkGroupSizeHintAttr *A = FD->
getAttr<WorkGroupSizeHintAttr>()) {
640 auto Eval = [&](
Expr *E) {
641 return E->EvaluateKnownConstInt(FD->
getASTContext()).getExtValue();
643 llvm::Metadata *AttrMDArgs[] = {
644 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getXDim()))),
645 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getYDim()))),
646 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getZDim())))};
647 Fn->setMetadata(
"work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));
650 if (
const ReqdWorkGroupSizeAttr *A = FD->
getAttr<ReqdWorkGroupSizeAttr>()) {
651 auto Eval = [&](Expr *E) {
652 return E->EvaluateKnownConstInt(FD->
getASTContext()).getExtValue();
654 llvm::Metadata *AttrMDArgs[] = {
655 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getXDim()))),
656 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getYDim()))),
657 llvm::ConstantAsMetadata::get(
Builder.getInt32(Eval(A->getZDim())))};
658 Fn->setMetadata(
"reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs));
661 if (
const OpenCLIntelReqdSubGroupSizeAttr *A =
662 FD->
getAttr<OpenCLIntelReqdSubGroupSizeAttr>()) {
663 llvm::Metadata *AttrMDArgs[] = {
664 llvm::ConstantAsMetadata::get(
Builder.getInt32(A->getSubGroupSize()))};
665 Fn->setMetadata(
"intel_reqd_sub_group_size",
666 llvm::MDNode::get(Context, AttrMDArgs));
672 const Stmt *Body =
nullptr;
673 if (
auto *FD = dyn_cast_or_null<FunctionDecl>(F))
675 else if (
auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(F))
676 Body = OMD->getBody();
678 if (
auto *CS = dyn_cast_or_null<CompoundStmt>(Body)) {
679 auto LastStmt = CS->body_rbegin();
680 if (LastStmt != CS->body_rend())
687 if (
SanOpts.has(SanitizerKind::Thread)) {
688 Fn->addFnAttr(
"sanitize_thread_no_checking_at_run_time");
689 Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
691 if (
SanOpts.has(SanitizerKind::Concurrency)) {
692 Fn->addFnAttr(
"sanitize_concurrency_no_checking_at_run_time");
693 Fn->removeFnAttr(llvm::Attribute::SanitizeConcurrency);
698bool CodeGenFunction::requiresReturnValueCheck()
const {
699 return requiresReturnValueNullabilityCheck() ||
705 auto *MD = dyn_cast_or_null<CXXMethodDecl>(D);
706 if (!MD || !MD->getDeclName().getAsIdentifierInfo() ||
707 !MD->getDeclName().getAsIdentifierInfo()->isStr(
"allocate") ||
708 (MD->getNumParams() != 1 && MD->getNumParams() != 2))
714 if (MD->getNumParams() == 2) {
715 auto *PT = MD->parameters()[1]->getType()->getAs<
PointerType>();
716 if (!PT || !PT->isVoidPointerType() ||
717 !PT->getPointeeType().isConstQualified())
724bool CodeGenFunction::isInAllocaArgument(
CGCXXABI &ABI, QualType Ty) {
729bool CodeGenFunction::hasInAllocaArg(
const CXXMethodDecl *MD) {
732 llvm::any_of(MD->
parameters(), [&](ParmVarDecl *P) {
733 return isInAllocaArgument(CGM.getCXXABI(), P->getType());
740 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD))
753 "Do not use a CodeGenFunction object for more than one function");
757 DidCallStackSave =
false;
759 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
766 assert(
CurFn->isDeclaration() &&
"Function already has body?");
771#define SANITIZER(NAME, ID) \
772 if (SanOpts.empty()) \
774 if (SanOpts.has(SanitizerKind::ID)) \
775 if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \
776 SanOpts.set(SanitizerKind::ID, false);
778#include "clang/Basic/Sanitizers.def"
783 const bool SanitizeBounds =
SanOpts.hasOneOf(SanitizerKind::Bounds);
785 bool NoSanitizeCoverage =
false;
788 no_sanitize_mask |=
Attr->getMask();
790 if (
Attr->hasCoverage())
791 NoSanitizeCoverage =
true;
795 SanOpts.Mask &= ~no_sanitize_mask;
796 if (no_sanitize_mask & SanitizerKind::Address)
797 SanOpts.set(SanitizerKind::KernelAddress,
false);
798 if (no_sanitize_mask & SanitizerKind::KernelAddress)
799 SanOpts.set(SanitizerKind::Address,
false);
800 if (no_sanitize_mask & SanitizerKind::HWAddress)
801 SanOpts.set(SanitizerKind::KernelHWAddress,
false);
802 if (no_sanitize_mask & SanitizerKind::KernelHWAddress)
803 SanOpts.set(SanitizerKind::HWAddress,
false);
805 if (SanitizeBounds && !
SanOpts.hasOneOf(SanitizerKind::Bounds))
806 Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds);
808 if (NoSanitizeCoverage &&
CGM.getCodeGenOpts().hasSanitizeCoverage())
809 Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);
812 if (
CGM.getCodeGenOpts().hasSanitizeBinaryMetadata()) {
813 if (no_sanitize_mask & SanitizerKind::Thread)
814 Fn->addFnAttr(
"no_sanitize_thread");
819 CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
822 if (
SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
823 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
824 if (
SanOpts.hasOneOf(SanitizerKind::HWAddress |
825 SanitizerKind::KernelHWAddress))
826 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
827 if (
SanOpts.has(SanitizerKind::MemtagStack))
828 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
829 if (
SanOpts.has(SanitizerKind::Thread))
830 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
831 if (
SanOpts.has(SanitizerKind::Concurrency))
832 Fn->addFnAttr(llvm::Attribute::SanitizeConcurrency);
833 if (
SanOpts.has(SanitizerKind::Type))
834 Fn->addFnAttr(llvm::Attribute::SanitizeType);
835 if (
SanOpts.has(SanitizerKind::NumericalStability))
836 Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
837 if (
SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
838 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
839 if (
SanOpts.has(SanitizerKind::AllocToken))
840 Fn->addFnAttr(llvm::Attribute::SanitizeAllocToken);
842 if (
SanOpts.has(SanitizerKind::SafeStack))
843 Fn->addFnAttr(llvm::Attribute::SafeStack);
844 if (
SanOpts.has(SanitizerKind::ShadowCallStack))
845 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
847 if (
SanOpts.has(SanitizerKind::Realtime))
851 Fn->addFnAttr(llvm::Attribute::SanitizeRealtime);
853 Fn->addFnAttr(llvm::Attribute::SanitizeRealtimeBlocking);
857 if (
SanOpts.hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink))
858 Fn->addFnAttr(llvm::Attribute::OptForFuzzing);
863 if (
SanOpts.hasOneOf(SanitizerKind::Thread | SanitizerKind::Concurrency)) {
864 if (
const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
865 const IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
868 (OMD->getSelector().isUnarySelector() && II->
isStr(
".cxx_destruct"))) {
877 if (D &&
SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
885 if (D &&
SanOpts.has(SanitizerKind::Null))
891 bool AlwaysXRayAttr =
false;
892 if (
const auto *XRayAttr = D ? D->
getAttr<XRayInstrumentAttr>() :
nullptr) {
893 if (
CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
895 CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
898 Fn->addFnAttr(
"function-instrument",
"xray-always");
899 AlwaysXRayAttr =
true;
901 if (XRayAttr->neverXRayInstrument())
902 Fn->addFnAttr(
"function-instrument",
"xray-never");
903 if (
const auto *LogArgs = D->
getAttr<XRayLogArgsAttr>())
905 Fn->addFnAttr(
"xray-log-args",
906 llvm::utostr(LogArgs->getArgumentCount()));
911 "xray-instruction-threshold",
912 llvm::itostr(
CGM.getCodeGenOpts().XRayInstructionThreshold));
916 if (
CGM.getCodeGenOpts().XRayIgnoreLoops)
917 Fn->addFnAttr(
"xray-ignore-loops");
919 if (!
CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
921 Fn->addFnAttr(
"xray-skip-exit");
923 if (!
CGM.getCodeGenOpts().XRayInstrumentationBundle.has(
925 Fn->addFnAttr(
"xray-skip-entry");
927 auto FuncGroups =
CGM.getCodeGenOpts().XRayTotalFunctionGroups;
928 if (FuncGroups > 1) {
930 CurFn->getName().bytes_end());
931 auto Group = crc32(FuncName) % FuncGroups;
932 if (Group !=
CGM.getCodeGenOpts().XRaySelectedFunctionGroup &&
934 Fn->addFnAttr(
"function-instrument",
"xray-never");
938 if (
CGM.getCodeGenOpts().getProfileInstr() !=
939 llvm::driver::ProfileInstrKind::ProfileNone) {
940 switch (
CGM.isFunctionBlockedFromProfileInstr(Fn, Loc)) {
942 Fn->addFnAttr(llvm::Attribute::SkipProfile);
945 Fn->addFnAttr(llvm::Attribute::NoProfile);
952 unsigned Count, Offset;
954 if (
const auto *
Attr =
955 D ? D->
getAttr<PatchableFunctionEntryAttr>() :
nullptr) {
956 Count =
Attr->getCount();
957 Offset =
Attr->getOffset();
958 Section =
Attr->getSection();
960 Count =
CGM.getCodeGenOpts().PatchableFunctionEntryCount;
961 Offset =
CGM.getCodeGenOpts().PatchableFunctionEntryOffset;
964 Section =
CGM.getCodeGenOpts().PatchableFunctionEntrySection;
965 if (Count && Offset <= Count) {
966 Fn->addFnAttr(
"patchable-function-entry", std::to_string(Count - Offset));
968 Fn->addFnAttr(
"patchable-function-prefix", std::to_string(Offset));
969 if (!Section.empty())
970 Fn->addFnAttr(
"patchable-function-entry-section", Section);
976 if (
CGM.getCodeGenOpts().HotPatch &&
979 llvm::Triple::CODE16)
980 Fn->addFnAttr(
"patchable-function",
"prologue-short-redirect");
983 if (
CGM.getCodeGenOpts().NoUseJumpTables)
984 Fn->addFnAttr(
"no-jump-tables",
"true");
987 if (
CGM.getCodeGenOpts().NoInlineLineTables)
988 Fn->addFnAttr(
"no-inline-line-tables");
991 if (
CGM.getCodeGenOpts().ProfileSampleAccurate)
992 Fn->addFnAttr(
"profile-sample-accurate");
994 if (!
CGM.getCodeGenOpts().SampleProfileFile.empty())
995 Fn->addFnAttr(
"use-sample-profile");
997 if (D && D->
hasAttr<CFICanonicalJumpTableAttr>())
998 Fn->addFnAttr(
"cfi-canonical-jump-table");
1000 if (D && D->
hasAttr<NoProfileFunctionAttr>())
1001 Fn->addFnAttr(llvm::Attribute::NoProfile);
1003 if (D && D->
hasAttr<HybridPatchableAttr>())
1004 Fn->addFnAttr(llvm::Attribute::HybridPatchable);
1008 if (
auto *A = D->
getAttr<FunctionReturnThunksAttr>()) {
1009 switch (A->getThunkType()) {
1010 case FunctionReturnThunksAttr::Kind::Keep:
1012 case FunctionReturnThunksAttr::Kind::Extern:
1013 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
1016 }
else if (
CGM.getCodeGenOpts().FunctionReturnThunks)
1017 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
1026 EmitKernelMetadata(FD, Fn);
1029 if (FD && FD->
hasAttr<ClspvLibclcBuiltinAttr>()) {
1030 Fn->setMetadata(
"clspv_libclc_builtin",
1037 if (FD &&
SanOpts.has(SanitizerKind::Function) &&
1039 llvm::isCallableCC(Fn->getCallingConv())) {
1041 llvm::LLVMContext &Ctx = Fn->getContext();
1042 llvm::MDBuilder MDB(Ctx);
1044 llvm::LLVMContext::MD_func_sanitize,
1045 MDB.createRTTIPointerPrologue(
1052 if (
SanOpts.has(SanitizerKind::NullabilityReturn)) {
1053 auto Nullability =
FnRetTy->getNullability();
1056 if (!(
SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&
1058 RetValNullabilityPrecondition =
1065 if (
CGM.getCodeGenOpts().CopyProf) {
1066 if (
const auto *MD = dyn_cast_or_null<CXXMethodDecl>(D)) {
1068 if (
const auto *CD = dyn_cast<CXXConstructorDecl>(MD)) {
1069 if (!CD->isMoveConstructor())
1071 CD->isCopyConstructor() ?
"copyprof-copy-ctor" :
"copyprof-ctor";
1073 Attr =
"copyprof-dtor";
1075 Attr =
"copyprof-copy-assign-op";
1077 if (!
Attr.empty()) {
1084 CGM.getCodeGenOpts().CopyProfStaticSizeThreshold)
1108 Fn->addFnAttr(llvm::Attribute::NoRecurse);
1111 llvm::fp::ExceptionBehavior FPExceptionBehavior =
1113 Builder.setDefaultConstrainedRounding(RM);
1114 Builder.setDefaultConstrainedExcept(FPExceptionBehavior);
1116 (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
1117 RM != llvm::RoundingMode::NearestTiesToEven))) {
1118 Builder.setIsFPConstrained(
true);
1119 Fn->addFnAttr(llvm::Attribute::StrictFP);
1125 CGM.getCodeGenOpts().StackAlignment))
1126 Fn->addFnAttr(
"stackrealign");
1130 Fn->removeFnAttr(
"zero-call-used-regs");
1133 llvm::StringMap<bool> FeatureMap;
1138 if (
T->getAArch64SMEAttributes() &
1145 std::optional<std::pair<unsigned, unsigned>> VScaleRange =
1149 CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
1158 llvm::Value *Poison = llvm::PoisonValue::get(
Int32Ty);
1163 Builder.SetInsertPoint(EntryBB);
1167 if (requiresReturnValueCheck()) {
1178 DI->emitFunctionStart(GD, Loc, StartLoc,
1179 DI->getFunctionType(FD, RetTy, Args),
CurFn,
1184 if (
CGM.getCodeGenOpts().InstrumentFunctions)
1185 CurFn->addFnAttr(
"instrument-function-entry",
"__cyg_profile_func_enter");
1186 if (
CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)
1187 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1188 "__cyg_profile_func_enter");
1189 if (
CGM.getCodeGenOpts().InstrumentFunctionEntryBare)
1190 CurFn->addFnAttr(
"instrument-function-entry-inlined",
1191 "__cyg_profile_func_enter_bare");
1198 if (
CGM.getCodeGenOpts().InstrumentForProfiling) {
1202 if (
CGM.getCodeGenOpts().CallFEntry)
1203 Fn->addFnAttr(
"fentry-call",
"true");
1205 Fn->addFnAttr(
"instrument-function-entry-inlined",
1208 if (
CGM.getCodeGenOpts().MNopMCount) {
1209 if (!
CGM.getCodeGenOpts().CallFEntry)
1210 CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)
1211 <<
"-mnop-mcount" <<
"-mfentry";
1212 Fn->addFnAttr(
"mnop-mcount");
1215 if (
CGM.getCodeGenOpts().RecordMCount) {
1216 if (!
CGM.getCodeGenOpts().CallFEntry)
1217 CGM.getDiags().Report(diag::err_opt_not_valid_without_opt)
1218 <<
"-mrecord-mcount" <<
"-mfentry";
1219 Fn->addFnAttr(
"mrecord-mcount");
1224 if (
CGM.getCodeGenOpts().PackedStack) {
1226 llvm::Triple::systemz)
1227 CGM.getDiags().Report(diag::err_opt_not_valid_on_target)
1228 <<
"-mpacked-stack";
1229 Fn->addFnAttr(
"packed-stack");
1232 if (!
CGM.getCodeGenOpts().ZOSPPA1Name)
1233 Fn->addFnAttr(
"zos-ppa1-name",
"");
1235 FD->
hasAttr<AsmLabelAttr>()) {
1236 std::string SrcName =
CGM.getMangledNameIgnoringAsmLabel(GD, FD);
1237 Fn->addFnAttr(
"zos-ppa1-name", SrcName);
1240 if (
CGM.getCodeGenOpts().WarnStackSize !=
UINT_MAX &&
1241 !
CGM.getDiags().isIgnored(diag::warn_fe_backend_frame_larger_than, Loc))
1242 Fn->addFnAttr(
"warn-stack-size",
1243 std::to_string(
CGM.getCodeGenOpts().WarnStackSize));
1255 auto AI =
CurFn->arg_begin();
1256 if (
CurFnInfo->getReturnInfo().isSRetAfterThis())
1259 &*AI, RetTy,
CurFnInfo->getReturnInfo().getIndirectAlign(),
false,
1261 if (!
CurFnInfo->getReturnInfo().getIndirectByVal()) {
1270 unsigned Idx =
CurFnInfo->getReturnInfo().getInAllocaFieldIndex();
1271 llvm::Function::arg_iterator EI =
CurFn->arg_end();
1303 if (FD->
hasAttr<HLSLShaderAttr>()) {
1304 CGM.getHLSLRuntime().emitEntryFunction(FD, Fn);
1310 if (
const CXXMethodDecl *MD = dyn_cast_if_present<CXXMethodDecl>(D);
1315 CGM.getCXXABI().EmitInstanceFunctionProlog(*
this);
1331 CXXThisValue = ThisFieldLValue.
getPointer(*
this);
1340 if (FD->hasCapturedVLAType()) {
1343 auto VAT = FD->getCapturedVLAType();
1344 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
1351 CXXThisValue = CXXABIThisValue;
1355 if (CXXABIThisValue) {
1357 SkippedChecks.
set(SanitizerKind::ObjectSize,
true);
1364 SkippedChecks.
set(SanitizerKind::Null,
true);
1368 Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks);
1375 if (!FD || !FD->
hasAttr<NakedAttr>()) {
1376 for (
const VarDecl *VD : Args) {
1381 if (
const ParmVarDecl *PVD = dyn_cast<ParmVarDecl>(VD))
1382 Ty = PVD->getOriginalType();
1392 DI->EmitLocation(
Builder, StartLoc);
1396 if (
const auto *VecWidth =
CurFuncDecl->getAttr<MinVectorWidthAttr>())
1397 LargestVectorWidth = VecWidth->getVectorWidth();
1399 if (
CGM.shouldEmitConvergenceTokens())
1406 if (
const CompoundStmt *S = dyn_cast<CompoundStmt>(Body))
1418 llvm::BasicBlock *SkipCountBB =
nullptr;
1440 if (F->isInterposable())
return;
1442 for (llvm::BasicBlock &BB : *F)
1443 for (llvm::Instruction &I : BB)
1447 F->setDoesNotThrow();
1457 if (
CGM.getCXXABI().HasThisReturn(GD))
1459 else if (
CGM.getCXXABI().hasMostDerivedReturn(GD))
1460 ResTy =
CGM.getContext().VoidPtrTy;
1461 CGM.getCXXABI().buildThisParam(*
this, Args);
1467 bool PassedParams =
true;
1469 if (
auto Inherited = CD->getInheritedConstructor())
1475 Args.push_back(Param);
1476 if (!Param->hasAttr<PassObjectSizeAttr>())
1480 getContext(), Param->getDeclContext(), Param->getLocation(),
1488 CGM.getCXXABI().addImplicitStructorParams(*
this, ResTy, Args);
1495 assert(Fn &&
"generating code for null Function");
1502 CGM.getTargetCodeGenInfo().checkFunctionABI(
CGM, FD);
1508 std::string FDInlineName = (Fn->getName() +
".inline").str();
1509 llvm::Module *M = Fn->getParent();
1510 llvm::Function *Clone = M->getFunction(FDInlineName);
1512 Clone = llvm::Function::Create(Fn->getFunctionType(),
1513 llvm::GlobalValue::InternalLinkage,
1514 Fn->getAddressSpace(), FDInlineName, M);
1515 Clone->setCallingConv(Fn->getCallingConv());
1516 Clone->setAttributes(Fn->getAttributes());
1517 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
1519 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
1529 if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) {
1530 std::string FDInlineName = (Fn->getName() +
".inline").str();
1531 llvm::Module *M = Fn->getParent();
1532 if (llvm::Function *Clone = M->getFunction(FDInlineName)) {
1533 Clone->replaceAllUsesWith(Fn);
1534 Clone->eraseFromParent();
1542 if (FD->
hasAttr<NoDebugAttr>()) {
1545 Fn->setSubprogram(
nullptr);
1547 DebugInfo =
nullptr;
1550 llvm::scope_exit Cleanup([
this] {
1552 DI->completeFunction();
1559 BodyRange = Body->getSourceRange();
1562 CurEHLocation = BodyRange.getEnd();
1574 if (SpecDecl->hasBody(SpecDecl))
1575 Loc = SpecDecl->getLocation();
1582 ShouldEmitLifetimeMarkers =
true;
1585 bool NeedsBypassDetection =
1586 ShouldEmitLifetimeMarkers ||
1587 (
CGM.getLangOpts().getTrivialAutoVarInit() !=
1589 if (NeedsBypassDetection)
1594 StartFunction(GD, ResTy, Fn, FnInfo, Args, Loc, BodyRange.getBegin());
1597 if (Body && isa_and_nonnull<CoroutineBodyStmt>(Body))
1605 CurFn->addFnAttr(llvm::Attribute::MustProgress);
1608 PGO->assignRegionCounters(GD,
CurFn);
1615 FD->
hasAttr<CUDAGlobalAttr>())
1616 CGM.getCUDARuntime().emitDeviceStub(*
this, Args);
1639 }
else if (DeviceKernelAttr::isOpenCLSpelling(
1640 FD->
getAttr<DeviceKernelAttr>()) &&
1643 for (
unsigned i = 0; i < Args.size(); ++i) {
1645 QualType ArgQualType = Args[i]->getType();
1647 CallArgs.
add(ArgRValue, ArgQualType);
1651 CGM.getTargetCodeGenInfo().setOCLKernelStubCallingConvention(FT);
1654 llvm::FunctionType *FTy =
CGM.getTypes().GetFunctionType(FnInfo);
1655 llvm::Constant *GDStubFunctionPointer =
1656 CGM.getRawFunctionPointer(GDStub, FTy);
1663 llvm_unreachable(
"no definition for emitted function");
1673 bool ShouldEmitUnreachable =
1674 CGM.getCodeGenOpts().StrictReturn ||
1676 if (
SanOpts.has(SanitizerKind::Return)) {
1677 auto CheckOrdinal = SanitizerKind::SO_Return;
1678 auto CheckHandler = SanitizerHandler::MissingReturn;
1680 llvm::Value *IsFalse =
Builder.getFalse();
1681 EmitCheck(std::make_pair(IsFalse, CheckOrdinal), CheckHandler,
1683 }
else if (ShouldEmitUnreachable) {
1684 if (
CGM.getCodeGenOpts().OptimizationLevel == 0)
1687 if (
SanOpts.has(SanitizerKind::Return) || ShouldEmitUnreachable) {
1689 Builder.ClearInsertionPoint();
1696 PGO->verifyCounterMap();
1699 StringRef Identifier =
1700 CurCodeDecl->getAttr<PersonalityAttr>()->getRoutine()->getName();
1701 llvm::FunctionCallee PersonalityRoutine =
1702 CGM.CreateRuntimeFunction(llvm::FunctionType::get(
CGM.Int32Ty,
true),
1703 Identifier, {},
true);
1709 if (!
CurFn->doesNotThrow())
1718 if (!S)
return false;
1735 IgnoreCaseStmts =
true;
1750 if (!S)
return false;
1770 if (!S)
return false;
1801 if (!AllowLabels &&
CGM.getCodeGenOpts().hasProfileClangInstr() &&
1802 CGM.getCodeGenOpts().MCDCCoverage)
1805 llvm::APSInt ResultInt;
1809 ResultBool = ResultInt.getBoolValue();
1817 llvm::APSInt &ResultInt,
1829 PGO->markStmtMaybeUsed(Cond);
1830 ResultInt = std::move(
Int);
1859 llvm::BasicBlock *FalseBlock, uint64_t TrueCount ,
1862 bool InstrumentRegions =
CGM.getCodeGenOpts().hasProfileClangInstr();
1866 const Stmt *CntrStmt = (CntrIdx ? CntrIdx : Cond);
1868 llvm::BasicBlock *ThenBlock =
nullptr;
1869 llvm::BasicBlock *ElseBlock =
nullptr;
1870 llvm::BasicBlock *NextBlock =
nullptr;
1875 llvm::BasicBlock *SkipIncrBlock =
1877 llvm::BasicBlock *SkipNextBlock =
nullptr;
1891 if (LOp == BO_LAnd) {
1892 SkipNextBlock = FalseBlock;
1893 ThenBlock = CounterIncrBlock;
1894 ElseBlock = (SkipIncrBlock ? SkipIncrBlock : SkipNextBlock);
1895 NextBlock = TrueBlock;
1910 else if (LOp == BO_LOr) {
1911 SkipNextBlock = TrueBlock;
1912 ThenBlock = (SkipIncrBlock ? SkipIncrBlock : SkipNextBlock);
1913 ElseBlock = CounterIncrBlock;
1914 NextBlock = FalseBlock;
1916 llvm_unreachable(
"Expected Opcode must be that of a Logical Operator");
1922 if (SkipIncrBlock) {
1946 const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock,
1948 const VarDecl *ConditionalDecl) {
1951 if (
const BinaryOperator *CondBOp = dyn_cast<BinaryOperator>(Cond)) {
1955 if (CondBOp->getOpcode() == BO_LAnd) {
1958 bool ConstantBool =
false;
1964 FalseBlock, TrueCount, LH);
1974 FalseBlock, TrueCount, LH, CondBOp);
1981 llvm::BasicBlock *LHSFalse =
2009 FalseBlock, TrueCount, LH);
2014 if (CondBOp->getOpcode() == BO_LOr) {
2017 bool ConstantBool =
false;
2023 FalseBlock, TrueCount, LH);
2033 FalseBlock, TrueCount, LH, CondBOp);
2038 llvm::BasicBlock *LHSTrue =
2046 uint64_t RHSCount = TrueCount - LHSCount;
2077 if (
const UnaryOperator *CondUOp = dyn_cast<UnaryOperator>(Cond)) {
2082 bool MCDCCondition =
CGM.getCodeGenOpts().hasProfileClangInstr() &&
2083 CGM.getCodeGenOpts().MCDCCoverage &&
2085 if (CondUOp->getOpcode() == UO_LNot && !MCDCCondition) {
2112 uint64_t LHSScaledTrueCount = 0;
2116 LHSScaledTrueCount = TrueCount * LHSRatio;
2125 LHSScaledTrueCount, LH, CondOp);
2133 TrueCount - LHSScaledTrueCount, LH, CondOp);
2139 if (
const CXXThrowExpr *Throw = dyn_cast<CXXThrowExpr>(Cond)) {
2161 const Expr *MCDCBaseExpr = Cond;
2168 MCDCBaseExpr = ConditionalOp;
2175 llvm::MDNode *Weights =
nullptr;
2176 llvm::MDNode *Unpredictable =
nullptr;
2182 if (
Call &&
CGM.getCodeGenOpts().OptimizationLevel != 0) {
2183 auto *FD = dyn_cast_or_null<FunctionDecl>(
Call->getCalleeDecl());
2184 if (FD && FD->
getBuiltinID() == Builtin::BI__builtin_unpredictable) {
2186 Unpredictable = MDHelper.createUnpredictable();
2192 llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH);
2193 if (CondV != NewCondV)
2198 Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);
2201 llvm::Instruction *BrInst =
Builder.CreateCondBr(CondV, TrueBlock, FalseBlock,
2202 Weights, Unpredictable);
2206 case HLSLControlFlowHintAttr::Microsoft_branch:
2207 case HLSLControlFlowHintAttr::Microsoft_flatten: {
2208 llvm::MDBuilder MDHelper(
CGM.getLLVMContext());
2210 llvm::ConstantInt *BranchHintConstant =
2212 HLSLControlFlowHintAttr::Spelling::Microsoft_branch
2213 ? llvm::ConstantInt::get(
CGM.Int32Ty, 1)
2214 : llvm::ConstantInt::get(
CGM.Int32Ty, 2);
2217 {MDHelper.createString(
"hlsl.controlflow.hint"),
2218 MDHelper.createConstant(BranchHintConstant)});
2219 BrInst->setMetadata(
"hlsl.controlflow.hint",
2220 llvm::MDNode::get(
CGM.getLLVMContext(), Vals));
2224 case HLSLControlFlowHintAttr::SpellingNotCalculated:
2232 llvm::Value *Arg =
nullptr;
2233 if ((ICEArguments & (1 << Idx)) == 0) {
2238 std::optional<llvm::APSInt>
Result =
2240 assert(
Result &&
"Expected argument to be a constant");
2249 CGM.ErrorUnsupported(S,
Type);
2261 llvm::Value *sizeInChars) {
2265 llvm::Value *baseSizeInChars
2269 llvm::Value *end = Builder.CreateInBoundsGEP(begin.
getElementType(),
2271 sizeInChars,
"vla.end");
2273 llvm::BasicBlock *originBB = CGF.
Builder.GetInsertBlock();
2281 llvm::PHINode *cur = Builder.CreatePHI(begin.
getType(), 2,
"vla.cur");
2288 Builder.CreateMemCpy(
Address(cur, CGF.
Int8Ty, curAlign), src, baseSizeInChars,
2293 Builder.CreateInBoundsGEP(CGF.
Int8Ty, cur, baseSizeInChars,
"vla.next");
2296 llvm::Value *done = Builder.CreateICmpEQ(next, end,
"vla-init.isdone");
2297 Builder.CreateCondBr(done, contBB, loopBB);
2298 cur->addIncoming(next, loopBB);
2316 if (
CGM.getContext().arePFPFieldsTriviallyCopyable(Field->getParent())) {
2317 uint64_t FieldSignature =
2318 llvm::getPointerAuthStableSipHash(
CGM.getPFPFieldName(Field));
2319 Disc = llvm::ConstantInt::get(
CGM.Int64Ty, FieldSignature);
2323 llvm::GlobalValue *DS =
CGM.getPFPDeactivationSymbol(Field);
2324 llvm::OperandBundleDef DSBundle(
"deactivation-symbol", DS);
2327 Builder.CreateCall(
CGM.getIntrinsic(llvm::Intrinsic::protected_field_ptr,
2346 llvm::Value *SizeVal;
2353 dyn_cast_or_null<VariableArrayType>(
2356 SizeVal = VlaSize.NumElts;
2358 if (!eltSize.
isOne())
2359 SizeVal =
Builder.CreateNUWMul(SizeVal,
CGM.getSize(eltSize));
2365 SizeVal =
CGM.getSize(size);
2373 if (!
CGM.getTypes().isZeroInitializable(Ty)) {
2377 llvm::Constant *NullConstant =
CGM.EmitNullConstant(Ty);
2379 llvm::GlobalVariable *NullVariable =
2380 new llvm::GlobalVariable(
CGM.getModule(), NullConstant->getType(),
2382 llvm::GlobalVariable::PrivateLinkage,
2383 NullConstant, Twine());
2385 NullVariable->setAlignment(NullAlign.
getAsAlign());
2391 Builder.CreateMemCpy(DestPtr, SrcPtr, SizeVal,
false);
2397 Builder.CreateMemSet(DestPtr,
Builder.getInt8(0), SizeVal,
false);
2410 if (!IndirectBranch)
2416 IndirectBranch->addDestination(BB);
2417 return llvm::BlockAddress::get(
CurFn->getType(), BB);
2422 if (IndirectBranch)
return IndirectBranch->getParent();
2427 llvm::Value *DestVal = TmpBuilder.CreatePHI(
Int8PtrTy, 0,
2428 "indirect.goto.dest");
2431 IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
2432 return IndirectBranch->getParent();
2444 llvm::Value *numVLAElements =
nullptr;
2456 baseType = elementType;
2457 return numVLAElements;
2471 llvm::ConstantInt *zero =
Builder.getInt32(0);
2472 gepIndices.push_back(zero);
2474 uint64_t countFromCLAs = 1;
2477 llvm::ArrayType *llvmArrayType =
2479 while (llvmArrayType) {
2482 llvmArrayType->getNumElements());
2484 gepIndices.push_back(zero);
2485 countFromCLAs *= llvmArrayType->getNumElements();
2489 dyn_cast<llvm::ArrayType>(llvmArrayType->getElementType());
2492 "LLVM and Clang types are out-of-synch");
2511 gepIndices,
"array.begin"),
2517 llvm::Value *numElements
2518 = llvm::ConstantInt::get(
SizeTy, countFromCLAs);
2522 numElements =
Builder.CreateNUWMul(numVLAElements, numElements);
2529 assert(vla &&
"type was not a variable array type!");
2536 llvm::Value *numElements =
nullptr;
2540 elementType =
type->getElementType();
2541 llvm::Value *vlaSize = VLASizeMap[
type->getSizeExpr()];
2542 assert(vlaSize &&
"no size for VLA!");
2543 assert(vlaSize->getType() ==
SizeTy);
2546 numElements = vlaSize;
2550 numElements =
Builder.CreateNUWMul(numElements, vlaSize);
2552 }
while ((
type =
getContext().getAsVariableArrayType(elementType)));
2554 return { numElements, elementType };
2560 assert(vla &&
"type was not a variable array type!");
2566 llvm::Value *VlaSize = VLASizeMap[Vla->
getSizeExpr()];
2567 assert(VlaSize &&
"no size for VLA!");
2568 assert(VlaSize->getType() ==
SizeTy);
2573 assert(
type->isVariablyModifiedType() &&
2574 "Must pass variably modified type to EmitVLASizes!");
2581 assert(
type->isVariablyModifiedType());
2583 const Type *ty =
type.getTypePtr();
2586#define TYPE(Class, Base)
2587#define ABSTRACT_TYPE(Class, Base)
2588#define NON_CANONICAL_TYPE(Class, Base)
2589#define DEPENDENT_TYPE(Class, Base) case Type::Class:
2590#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
2591#include "clang/AST/TypeNodes.inc"
2592 llvm_unreachable(
"unexpected dependent type!");
2598 case Type::ExtVector:
2599 case Type::ConstantMatrix:
2603 case Type::TemplateSpecialization:
2604 case Type::ObjCTypeParam:
2605 case Type::ObjCObject:
2606 case Type::ObjCInterface:
2607 case Type::ObjCObjectPointer:
2609 case Type::HLSLInlineSpirv:
2610 case Type::PredefinedSugar:
2611 llvm_unreachable(
"type class is never variably-modified!");
2613 case Type::Adjusted:
2625 case Type::BlockPointer:
2629 case Type::LValueReference:
2630 case Type::RValueReference:
2634 case Type::MemberPointer:
2638 case Type::ArrayParameter:
2639 case Type::ConstantArray:
2640 case Type::IncompleteArray:
2645 case Type::VariableArray: {
2654 llvm::Value *&entry = VLASizeMap[sizeExpr];
2662 if (
SanOpts.has(SanitizerKind::VLABound)) {
2663 auto CheckOrdinal = SanitizerKind::SO_VLABound;
2664 auto CheckHandler = SanitizerHandler::VLABoundNotPositive;
2666 llvm::Value *
Zero = llvm::Constant::getNullValue(size->getType());
2668 llvm::Value *CheckCondition =
2672 llvm::Constant *StaticArgs[] = {
2675 EmitCheck(std::make_pair(CheckCondition, CheckOrdinal),
2676 CheckHandler, StaticArgs, size);
2689 case Type::FunctionProto:
2690 case Type::FunctionNoProto:
2696 case Type::UnaryTransform:
2697 case Type::Attributed:
2698 case Type::BTFTagAttributed:
2699 case Type::OverflowBehavior:
2700 case Type::HLSLAttributedResource:
2701 case Type::SubstTemplateTypeParm:
2702 case Type::MacroQualified:
2703 case Type::CountAttributed:
2704 case Type::LateParsedAttr:
2710 case Type::Decltype:
2712 case Type::DeducedTemplateSpecialization:
2713 case Type::PackIndexing:
2717 case Type::TypeOfExpr:
2730 }
while (
type->isVariablyModifiedType());
2734 if (
getContext().getBuiltinVaListType()->isArrayType())
2749 assert(
Init.hasValue() &&
"Invalid DeclRefExpr initializer!");
2751 if (
CGM.getCodeGenOpts().hasReducedDebugInfo())
2767 llvm::Instruction *inst =
new llvm::BitCastInst(value, value->getType(),
"",
2771 protection.Inst = inst;
2776 if (!protection.Inst)
return;
2779 protection.Inst->eraseFromParent();
2785 llvm::Value *Alignment,
2786 llvm::Value *OffsetValue) {
2787 if (Alignment->getType() !=
IntPtrTy)
2790 if (OffsetValue && OffsetValue->getType() !=
IntPtrTy)
2793 llvm::Value *TheCheck =
nullptr;
2794 if (
SanOpts.has(SanitizerKind::Alignment)) {
2795 llvm::Value *PtrIntValue =
2799 bool IsOffsetZero =
false;
2800 if (
const auto *CI = dyn_cast<llvm::ConstantInt>(OffsetValue))
2801 IsOffsetZero = CI->isZero();
2804 PtrIntValue =
Builder.CreateSub(PtrIntValue, OffsetValue,
"offsetptr");
2807 llvm::Value *
Zero = llvm::ConstantInt::get(
IntPtrTy, 0);
2810 llvm::Value *MaskedPtr =
Builder.CreateAnd(PtrIntValue, Mask,
"maskedptr");
2811 TheCheck =
Builder.CreateICmpEQ(MaskedPtr,
Zero,
"maskcond");
2813 llvm::Instruction *Assumption =
Builder.CreateAlignmentAssumption(
2814 CGM.getDataLayout(), PtrValue, Alignment, OffsetValue);
2816 if (!
SanOpts.has(SanitizerKind::Alignment))
2819 OffsetValue, TheCheck, Assumption);
2825 llvm::Value *Alignment,
2826 llvm::Value *OffsetValue) {
2835 llvm::Value *AnnotatedVal,
2836 StringRef AnnotationStr,
2838 const AnnotateAttr *
Attr) {
2841 CGM.EmitAnnotationString(AnnotationStr),
2842 CGM.EmitAnnotationUnit(Location),
2843 CGM.EmitAnnotationLineNo(Location),
2846 Args.push_back(
CGM.EmitAnnotationArgs(
Attr));
2847 return Builder.CreateCall(AnnotationFn, Args);
2851 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2854 {V->getType(), CGM.ConstGlobalsPtrTy}),
2860 assert(D->
hasAttr<AnnotateAttr>() &&
"no annotate attribute");
2861 llvm::Value *
V =
Addr.emitRawPointer(*
this);
2862 llvm::Type *VTy =
V->getType();
2863 auto *PTy = dyn_cast<llvm::PointerType>(VTy);
2864 unsigned AS = PTy ? PTy->getAddressSpace() : 0;
2865 llvm::PointerType *IntrinTy =
2866 llvm::PointerType::get(
CGM.getLLVMContext(), AS);
2867 llvm::Function *F =
CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
2868 {IntrinTy,
CGM.ConstGlobalsPtrTy});
2874 if (VTy != IntrinTy)
2887 assert(!CGF->IsSanitizerScope);
2888 CGF->IsSanitizerScope =
true;
2892 CGF->IsSanitizerScope =
false;
2896 const llvm::Twine &Name,
2897 llvm::BasicBlock::iterator InsertPt)
const {
2900 I->setNoSanitizeMetadata();
2904 llvm::Instruction *I,
const llvm::Twine &Name,
2905 llvm::BasicBlock::iterator InsertPt)
const {
2906 llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, InsertPt);
2908 CGF->InsertHelper(I, Name, InsertPt);
2930 if (!
CGM.getCodeGenOpts().SanitizeStats)
2933 llvm::IRBuilder<> IRB(
Builder.GetInsertPoint());
2934 IRB.SetCurrentDebugLocation(
Builder.getCurrentDebugLocation());
2935 CGM.getSanStats().create(IRB, SSK);
2947 Salt = Info.CFISalt;
2949 Bundles.emplace_back(
"kcfi",
CGM.CreateKCFITypeId(FP->
desugar(), Salt));
2953CodeGenFunction::FormAArch64ResolverCondition(
const FMVResolverOption &RO) {
2954 return RO.Features.empty() ?
nullptr : EmitAArch64CpuSupports(RO.Features);
2958CodeGenFunction::FormX86ResolverCondition(
const FMVResolverOption &RO) {
2961 if (RO.Architecture) {
2962 StringRef
Arch = *RO.Architecture;
2965 if (
Arch.starts_with(
"x86-64"))
2971 if (!RO.Features.empty()) {
2972 llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Features);
2980 llvm::Function *Resolver,
2982 llvm::Function *FuncToReturn,
2983 bool SupportsIFunc) {
2984 if (SupportsIFunc) {
2985 Builder.CreateRet(FuncToReturn);
2990 llvm::make_pointer_range(Resolver->args()));
2992 llvm::CallInst *
Result = Builder.CreateCall(FuncToReturn, Args);
2993 Result->setTailCallKind(llvm::CallInst::TCK_MustTail);
2995 if (Resolver->getReturnType()->isVoidTy())
2996 Builder.CreateRetVoid();
2998 Builder.CreateRet(
Result);
3004 llvm::Triple::ArchType ArchType =
3008 case llvm::Triple::x86:
3009 case llvm::Triple::x86_64:
3012 case llvm::Triple::aarch64:
3015 case llvm::Triple::riscv32:
3016 case llvm::Triple::riscv64:
3017 case llvm::Triple::riscv32be:
3018 case llvm::Triple::riscv64be:
3021 case llvm::Triple::ppc:
3022 case llvm::Triple::ppc64:
3030 "Only implemented for x86, AArch64, RISC-V, and PowerPC AIX");
3057 Builder.SetInsertPoint(CurBlock);
3059 if (!RO.Architecture && RO.Features.empty()) {
3062 assert(&RO == Options.end() - 1 &&
3063 "Default or Generic case must be last");
3064 Builder.CreateRet(RO.Function);
3073 assert(RO.Features.size() == 1 &&
3074 "for now one feature requirement per version");
3076 StringRef FeatureStr = RO.Features[0];
3077 StringRef BuiltinCpuSupportsArg;
3078 bool IsNegated =
false;
3080 if (FeatureStr.starts_with(
"cpu=")) {
3082 StringRef CPU = FeatureStr.split(
"=").second.trim();
3083 BuiltinCpuSupportsArg = llvm::StringSwitch<StringRef>(CPU)
3084#define PPC_AIX_CLONES_CPU(CPU_NAME, AIX_BUILTIN_CPU_SUPPORTS_NAME, _) \
3085 .Case(CPU_NAME, AIX_BUILTIN_CPU_SUPPORTS_NAME)
3086#include "llvm/TargetParser/PPCTargetParser.def"
3092 if (FeatureStr.starts_with(
"no-")) {
3094 FeatureStr = FeatureStr.drop_front(3);
3098 BuiltinCpuSupportsArg =
3099 llvm::StringSwitch<StringRef>(FeatureStr)
3100#define PPC_AIX_CLONES_FEATURE(FEATURE_NAME, AIX_BUILTIN_CPU_SUPPORTS_NAME, _, \
3102 .Case(FEATURE_NAME, AIX_BUILTIN_CPU_SUPPORTS_NAME)
3103#include "llvm/TargetParser/PPCTargetParser.def"
3108 assert(!BuiltinCpuSupportsArg.empty() &&
3109 "Feature without runtime detection should have been rejected in "
3113 assert(
getContext().getTargetInfo().validateCpuSupports(
3114 BuiltinCpuSupportsArg));
3118 Builder.getInt1Ty(), BuiltinCpuSupportsArg);
3129 Builder.SetInsertPoint(ThenBlock);
3130 Builder.CreateRet(RO.Function);
3133 llvm_unreachable(
"Default case missing");
3140 llvm::Triple::OSType::Linux) {
3141 CGM.getDiags().Report(diag::err_os_unsupport_riscv_fmv);
3146 Builder.SetInsertPoint(CurBlock);
3150 bool HasDefault =
false;
3151 unsigned DefaultIndex = 0;
3154 for (
unsigned Index = 0; Index < Options.size(); Index++) {
3156 if (Options[Index].Features.empty()) {
3158 DefaultIndex = Index;
3162 Builder.SetInsertPoint(CurBlock);
3188 for (StringRef Feat : Options[Index].Features) {
3189 std::vector<std::string> FeatStr =
3192 assert(FeatStr.size() == 1 &&
"Feature string not delimited");
3194 std::string &CurrFeat = FeatStr.front();
3195 if (CurrFeat[0] ==
'+')
3196 TargetAttrFeats.push_back(CurrFeat.substr(1));
3199 if (TargetAttrFeats.empty())
3202 for (std::string &Feat : TargetAttrFeats)
3203 CurrTargetAttrFeats.push_back(Feat);
3205 Builder.SetInsertPoint(CurBlock);
3208 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
3211 Options[Index].
Function, SupportsIFunc);
3214 Builder.SetInsertPoint(CurBlock);
3215 Builder.CreateCondBr(FeatsCondition, RetBlock, ElseBlock);
3217 CurBlock = ElseBlock;
3222 Builder.SetInsertPoint(CurBlock);
3229 Builder.SetInsertPoint(CurBlock);
3235 assert(!Options.empty() &&
"No multiversion resolver options found");
3236 assert(Options.back().Features.size() == 0 &&
"Default case must be last");
3238 assert(SupportsIFunc &&
3239 "Multiversion resolver requires target IFUNC support");
3240 bool AArch64CpuInitialized =
false;
3245 if (RO.Function ==
nullptr)
3248 Builder.SetInsertPoint(CurBlock);
3249 llvm::Value *
Condition = FormAArch64ResolverCondition(RO);
3258 if (!AArch64CpuInitialized) {
3259 Builder.SetInsertPoint(CurBlock->begin());
3260 EmitAArch64CpuInit();
3261 AArch64CpuInitialized =
true;
3262 Builder.SetInsertPoint(CurBlock);
3265 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
3274 Builder.SetInsertPoint(CurBlock);
3285 Builder.SetInsertPoint(CurBlock);
3289 Builder.SetInsertPoint(CurBlock);
3290 llvm::Value *
Condition = FormX86ResolverCondition(RO);
3294 assert(&RO == Options.end() - 1 &&
3295 "Default or Generic case must be last");
3301 llvm::BasicBlock *RetBlock =
createBasicBlock(
"resolver_return", Resolver);
3310 Builder.SetInsertPoint(CurBlock);
3323 llvm::Value *OffsetValue, llvm::Value *TheCheck,
3324 llvm::Instruction *Assumption) {
3325 assert(isa_and_nonnull<llvm::CallInst>(Assumption) &&
3327 llvm::Intrinsic::getOrInsertDeclaration(
Builder.getModule(),
3328 llvm::Intrinsic::assume) &&
3329 "Assumption should be a call to llvm.assume().");
3330 assert(&(
Builder.GetInsertBlock()->back()) == Assumption &&
3331 "Assumption should be the last instruction of the basic block, "
3332 "since the basic block is still being generated.");
3334 if (!
SanOpts.has(SanitizerKind::Alignment))
3344 Assumption->removeFromParent();
3347 auto CheckOrdinal = SanitizerKind::SO_Alignment;
3348 auto CheckHandler = SanitizerHandler::AlignmentAssumption;
3352 OffsetValue =
Builder.getInt1(
false);
3357 llvm::Value *DynamicData[] = {Ptr, Alignment, OffsetValue};
3358 EmitCheck({std::make_pair(TheCheck, CheckOrdinal)}, CheckHandler,
3359 StaticData, DynamicData);
3370 return DI->SourceLocToDebugLoc(Location);
3372 return llvm::DebugLoc();
3376CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
3387 llvm::Type *CondTy = Cond->getType();
3388 assert(CondTy->isIntegerTy(1) &&
"expecting condition to be a boolean");
3389 llvm::Function *FnExpect =
3391 llvm::Value *ExpectedValueOfCond =
3393 return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond},
3394 Cond->getName() +
".expval");
3396 llvm_unreachable(
"Unknown Likelihood");
3400 unsigned NumElementsDst,
3401 const llvm::Twine &Name) {
3403 unsigned NumElementsSrc = SrcTy->getNumElements();
3404 if (NumElementsSrc == NumElementsDst)
3407 std::vector<int> ShuffleMask(NumElementsDst, -1);
3408 for (
unsigned MaskIdx = 0;
3409 MaskIdx < std::min<>(NumElementsDst, NumElementsSrc); ++MaskIdx)
3410 ShuffleMask[MaskIdx] = MaskIdx;
3412 return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name);
3425 Discriminator =
Builder.getSize(0);
3427 llvm::Value *Args[] = {Key, Discriminator};
3428 Bundles.emplace_back(
"ptrauth", Args);
3434 unsigned IntrinsicID) {
3441 if (!Discriminator) {
3446 auto OrigType =
Pointer->getType();
3464 llvm::Intrinsic::ptrauth_sign);
3470 auto StripIntrinsic = CGF.
CGM.
getIntrinsic(llvm::Intrinsic::ptrauth_strip);
3474 auto OrigType =
Pointer->getType();
3491 llvm::Intrinsic::ptrauth_auth);
3495 llvm::Instruction *KeyInstruction, llvm::Value *Backup) {
3497 DI->addInstToCurrentSourceAtom(KeyInstruction, Backup);
3501 llvm::Instruction *KeyInstruction, llvm::Value *Backup, uint64_t Atom) {
3503 DI->addInstToSpecificSourceAtom(KeyInstruction, Backup, Atom);
3507 llvm::Value *Backup) {
3510 DI->addInstToCurrentSourceAtom(KeyInstruction, Backup);
3517 if (
getContext().arePFPFieldsTriviallyCopyable(Field.Field->getParent()))
3521 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 matchesStlAllocatorFn(const Decl *D, const ASTContext &Ctx)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Result
Implement __builtin_bit_cast and related operations.
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.
QualType getFunctionObjectParameterType() const
bool isCopyAssignmentOperator() const
Determine whether this is a copy-assignment operator, regardless of whether it was declared implicitl...
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.
This is an opaque type for sizes expressed in character units.
bool isZero() const
Test whether the quantity equals zero.
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
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
Test whether the quantity equals one.
@ 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
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::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID, bool EnsureInsertPoint=true)
Emit a call to trap or debugtrap.
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...
Address EmitZOSVAListRef(const Expr *E)
Emit a "reference" to a __builtin_zos_va_list; this is always the address of the expression,...
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,...
const FunctionDecl * getCurrentFunctionDecl() const
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitTrapCallAndMakeUnreachable()
Emit a call to '@llvm.trap()' and clear the current insert point.
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.
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.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
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.
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, const 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.
RoundingMode getDefaultRoundingMode() const
Represents a parameter to a function.
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.
void checkTargetFeatures(ASTContext &Ctx, DiagnosticsEngine &Diags, const LangOptions &LangOpts, const CallExpr *E, const FunctionDecl *Caller, const FunctionDecl *TargetDecl)
Check that a call to a target-specific builtin has the required target features enabled in the caller...
@ 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
Top level wrappers for InstallAPI frontend operations.
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.
const FunctionProtoType * T
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....
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.