clang: lib/CodeGen/CodeGenFunction.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
38#include "llvm/ADT/ArrayRef.h"
39#include "llvm/Frontend/OpenMP/OMPIRBuilder.h"
40#include "llvm/IR/DataLayout.h"
41#include "llvm/IR/Dominators.h"
42#include "llvm/IR/FPEnv.h"
43#include "llvm/IR/Instruction.h"
44#include "llvm/IR/IntrinsicInst.h"
45#include "llvm/IR/Intrinsics.h"
46#include "llvm/IR/MDBuilder.h"
47#include "llvm/Support/CRC.h"
48#include "llvm/Support/xxhash.h"
49#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
50#include "llvm/Transforms/Utils/PromoteMemToReg.h"
51#include
52
53using namespace clang;
54using namespace CodeGen;
55
56namespace llvm {
58}
59
60
61
64 if (CGOpts.DisableLifetimeMarkers)
65 return false;
66
67
68 if (CGOpts.SanitizeAddressUseAfterScope ||
69 LangOpts.Sanitize.has(SanitizerKind::HWAddress) ||
70 LangOpts.Sanitize.has(SanitizerKind::Memory))
71 return true;
72
73
74 return CGOpts.OptimizationLevel != 0;
75}
76
77CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext)
79 Builder(cgm, cgm.getModule().getContext(), llvm::ConstantFolder(),
81 SanOpts(CGM.getLangOpts().Sanitize), CurFPFeatures(CGM.getLangOpts()),
82 DebugInfo(CGM.getModuleDebugInfo()), PGO(cgm),
83 ShouldEmitLifetimeMarkers(
85 if (!suppressNewContext)
86 CGM.getCXXABI().getMangleContext().startNewFunction();
87 EHStack.setCGF(this);
88
89 SetFastMathFlags(CurFPFeatures);
90}
91
92CodeGenFunction::~CodeGenFunction() {
95 "missed to deactivate a cleanup");
96
99
100
101
102
103
104
107}
108
109
110
111llvm::fp::ExceptionBehavior
113
114 switch (Kind) {
118 default:
119 llvm_unreachable("Unsupported FP Exception Behavior");
120 }
121}
122
124 llvm::FastMathFlags FMF;
125 FMF.setAllowReassoc(FPFeatures.getAllowFPReassociate());
126 FMF.setNoNaNs(FPFeatures.getNoHonorNaNs());
127 FMF.setNoInfs(FPFeatures.getNoHonorInfs());
128 FMF.setNoSignedZeros(FPFeatures.getNoSignedZero());
129 FMF.setAllowReciprocal(FPFeatures.getAllowReciprocal());
130 FMF.setApproxFunc(FPFeatures.getAllowApproxFunc());
132 Builder.setFastMathFlags(FMF);
133}
134
137 : CGF(CGF) {
139}
140
143 : CGF(CGF) {
144 ConstructorHelper(FPFeatures);
145}
146
147void CodeGenFunction::CGFPOptionsRAII::ConstructorHelper(FPOptions FPFeatures) {
148 OldFPFeatures = CGF.CurFPFeatures;
149 CGF.CurFPFeatures = FPFeatures;
150
151 OldExcept = CGF.Builder.getDefaultConstrainedExcept();
152 OldRounding = CGF.Builder.getDefaultConstrainedRounding();
153
154 if (OldFPFeatures == FPFeatures)
155 return;
156
157 FMFGuard.emplace(CGF.Builder);
158
159 llvm::RoundingMode NewRoundingBehavior = FPFeatures.getRoundingMode();
160 CGF.Builder.setDefaultConstrainedRounding(NewRoundingBehavior);
161 auto NewExceptionBehavior =
164 CGF.Builder.setDefaultConstrainedExcept(NewExceptionBehavior);
165
166 CGF.SetFastMathFlags(FPFeatures);
167
168 assert((CGF.CurFuncDecl == nullptr || CGF.Builder.getIsFPConstrained() ||
169 isa(CGF.CurFuncDecl) ||
170 isa(CGF.CurFuncDecl) ||
171 (NewExceptionBehavior == llvm::fp::ebIgnore &&
172 NewRoundingBehavior == llvm::RoundingMode::NearestTiesToEven)) &&
173 "FPConstrained should be enabled on entire function");
174
175 auto mergeFnAttrValue = [&](StringRef Name, bool Value) {
176 auto OldValue =
177 CGF.CurFn->getFnAttribute(Name).getValueAsBool();
178 auto NewValue = OldValue & Value;
179 if (OldValue != NewValue)
180 CGF.CurFn->addFnAttr(Name, llvm::toStringRef(NewValue));
181 };
182 mergeFnAttrValue("no-infs-fp-math", FPFeatures.getNoHonorInfs());
183 mergeFnAttrValue("no-nans-fp-math", FPFeatures.getNoHonorNaNs());
184 mergeFnAttrValue("no-signed-zeros-fp-math", FPFeatures.getNoSignedZero());
185 mergeFnAttrValue(
186 "unsafe-fp-math",
187 FPFeatures.getAllowFPReassociate() && FPFeatures.getAllowReciprocal() &&
188 FPFeatures.getAllowApproxFunc() && FPFeatures.getNoSignedZero() &&
190}
191
193 CGF.CurFPFeatures = OldFPFeatures;
194 CGF.Builder.setDefaultConstrainedExcept(OldExcept);
195 CGF.Builder.setDefaultConstrainedRounding(OldRounding);
196}
197
207 MightBeSigned
209 nullptr, IsKnownNonNull)
212}
213
217 return ::makeNaturalAlignAddrLValue(V, T, false,
218 true, *this,
219 IsKnownNonNull);
220}
221
224 return ::makeNaturalAlignAddrLValue(V, T, true,
225 true, *this);
226}
227
230 return ::makeNaturalAlignAddrLValue(V, T, false,
231 false, *this);
232}
233
236 return ::makeNaturalAlignAddrLValue(V, T, true,
237 false, *this);
238}
239
242}
243
246}
247
249 llvm::Type *LLVMTy) {
251}
252
254 type = type.getCanonicalType();
255 while (true) {
256 switch (type->getTypeClass()) {
257#define TYPE(name, parent)
258#define ABSTRACT_TYPE(name, parent)
259#define NON_CANONICAL_TYPE(name, parent) case Type:📛
260#define DEPENDENT_TYPE(name, parent) case Type:📛
261#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(name, parent) case Type:📛
262#include "clang/AST/TypeNodes.inc"
263 llvm_unreachable("non-canonical or dependent type in IR-generation");
264
265 case Type::Auto:
266 case Type::DeducedTemplateSpecialization:
267 llvm_unreachable("undeduced type in IR-generation");
268
269
270 case Type::Builtin:
271 case Type::Pointer:
272 case Type::BlockPointer:
273 case Type::LValueReference:
274 case Type::RValueReference:
275 case Type::MemberPointer:
276 case Type::Vector:
277 case Type::ExtVector:
278 case Type::ConstantMatrix:
279 case Type::FunctionProto:
280 case Type::FunctionNoProto:
281 case Type::Enum:
282 case Type::ObjCObjectPointer:
283 case Type::Pipe:
284 case Type::BitInt:
285 case Type::HLSLAttributedResource:
287
288
289 case Type::Complex:
291
292
293 case Type::ConstantArray:
294 case Type::IncompleteArray:
295 case Type::VariableArray:
296 case Type::Record:
297 case Type::ObjCObject:
298 case Type::ObjCInterface:
299 case Type::ArrayParameter:
301
302
303 case Type::Atomic:
304 type = cast(type)->getValueType();
305 continue;
306 }
307 llvm_unreachable("unknown type kind!");
308 }
309}
310
312
313
314 llvm::BasicBlock *CurBB = Builder.GetInsertBlock();
315
316 if (CurBB) {
317 assert(!CurBB->getTerminator() && "Unexpected terminated block.");
318
319
320
325 } else
327 return llvm::DebugLoc();
328 }
329
330
331
332
334 llvm::BranchInst *BI =
336 if (BI && BI->isUnconditional() &&
338
339
340 llvm::DebugLoc Loc = BI->getDebugLoc();
341 Builder.SetInsertPoint(BI->getParent());
342 BI->eraseFromParent();
345 return Loc;
346 }
347 }
348
349
350
351
352
354 return llvm::DebugLoc();
355}
356
358 if (!BB) return;
359 if (!BB->use_empty()) {
360 CGF.CurFn->insert(CGF.CurFn->end(), BB);
361 return;
362 }
363 delete BB;
364}
365
367 assert(BreakContinueStack.empty() &&
368 "mismatched push/pop in break/continue stack!");
370 "mismatched push/pop of cleanups in EHStack!");
372 "mismatched activate/deactivate of cleanups!");
373
377 "mismatched push/pop in convergence stack!");
378 }
379
380 bool OnlySimpleReturnStmts = NumSimpleReturnExprs > 0
381 && NumSimpleReturnExprs == NumReturnExprs
383
384
385
386
387
388
389
390
391
392
393
394
396 if (OnlySimpleReturnStmts)
397 DI->EmitLocation(Builder, LastStopPoint);
398 else
399 DI->EmitLocation(Builder, EndLoc);
400 }
401
402
403
404
405
407 bool HasOnlyLifetimeMarkers =
409 bool EmitRetDbgLoc = !HasCleanups || HasOnlyLifetimeMarkers;
410
411 std::optional OAL;
412 if (HasCleanups) {
413
414
416 if (OnlySimpleReturnStmts)
417 DI->EmitLocation(Builder, EndLoc);
418 else
419
420
422 }
423
425 }
426
427
429
432 CurFn->addFnAttr("instrument-function-exit", "__cyg_profile_func_exit");
434 CurFn->addFnAttr("instrument-function-exit-inlined",
435 "__cyg_profile_func_exit");
436 }
437
438
441
442
443
447
449 "did not remove all scopes from cleanup stack!");
450
451
452
453 if (IndirectBranch) {
454 EmitBlock(IndirectBranch->getParent());
455 Builder.ClearInsertionPoint();
456 }
457
458
459
460 if (!EscapedLocals.empty()) {
461
462
464 EscapeArgs.resize(EscapedLocals.size());
465 for (auto &Pair : EscapedLocals)
466 EscapeArgs[Pair.second] = Pair.first;
467 llvm::Function *FrameEscapeFn = llvm::Intrinsic::getOrInsertDeclaration(
468 &CGM.getModule(), llvm::Intrinsic::localescape);
470 }
471
472
475 Ptr->eraseFromParent();
476
477
478
479 if (PostAllocaInsertPt) {
480 llvm::Instruction *PostPtr = PostAllocaInsertPt;
481 PostAllocaInsertPt = nullptr;
482 PostPtr->eraseFromParent();
483 }
484
485
486
487 if (IndirectBranch) {
488 llvm::PHINode *PN = castllvm::PHINode(IndirectBranch->getAddress());
489 if (PN->getNumIncomingValues() == 0) {
490 PN->replaceAllUsesWith(llvm::PoisonValue::get(PN->getType()));
491 PN->eraseFromParent();
492 }
493 }
494
496 EmitIfUsed(*this, TerminateLandingPad);
499
500 for (const auto &FuncletAndParent : TerminateFunclets)
501 EmitIfUsed(*this, FuncletAndParent.second);
502
504 EmitDeclMetadata();
505
506 for (const auto &R : DeferredReplacements) {
507 if (llvm::Value *Old = R.first) {
508 Old->replaceAllUsesWith(R.second);
509 castllvm::Instruction(Old)->eraseFromParent();
510 }
511 }
512 DeferredReplacements.clear();
513
514
515
516
517
518
519
521 llvm::DominatorTree DT(*CurFn);
522 llvm::PromoteMemToReg(
525 }
526
527
528 for (llvm::Argument &A : CurFn->args())
529 if (auto *VT = dyn_castllvm::VectorType(A.getType()))
530 LargestVectorWidth =
531 std::max((uint64_t)LargestVectorWidth,
532 VT->getPrimitiveSizeInBits().getKnownMinValue());
533
534
535 if (auto *VT = dyn_castllvm::VectorType(CurFn->getReturnType()))
536 LargestVectorWidth =
537 std::max((uint64_t)LargestVectorWidth,
538 VT->getPrimitiveSizeInBits().getKnownMinValue());
539
542
543
544
545
546
547
548
549
550 if (getContext().getTargetInfo().getTriple().isX86())
551 CurFn->addFnAttr("min-legal-vector-width",
552 llvm::utostr(LargestVectorWidth));
553
554
555 std::optional<std::pair<unsigned, unsigned>> VScaleRange =
557 if (VScaleRange) {
558 CurFn->addFnAttr(llvm::Attribute::getWithVScaleRangeArgs(
559 getLLVMContext(), VScaleRange->first, VScaleRange->second));
560 }
561
562
564 Builder.ClearInsertionPoint();
566 }
568 auto *RetAlloca =
570 if (RetAlloca && RetAlloca->use_empty()) {
571 RetAlloca->eraseFromParent();
573 }
574 }
575}
576
577
578
583 return false;
585 return false;
586 return true;
587}
588
591 return false;
593}
594
595
596
599}
600
601
602
608}
609
615}
616
617llvm::ConstantInt *
619
620
623 std::string Mangled;
624 llvm::raw_string_ostream Out(Mangled);
626 return llvm::ConstantInt::get(
628}
629
630void CodeGenFunction::EmitKernelMetadata(const FunctionDecl *FD,
631 llvm::Function *Fn) {
632 if (!FD->hasAttr() && !FD->hasAttr())
633 return;
634
636
638
641 getContext().getTargetInfo().getTriple().isSPIRV())))
642 return;
643
644 if (const VecTypeHintAttr *A = FD->getAttr()) {
645 QualType HintQTy = A->getTypeHint();
647 bool IsSignedInteger =
650 llvm::Metadata *AttrMDArgs[] = {
651 llvm::ConstantAsMetadata::get(llvm::UndefValue::get(
653 llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(
654 llvm::IntegerType::get(Context, 32),
655 llvm::APInt(32, (uint64_t)(IsSignedInteger ? 1 : 0))))};
656 Fn->setMetadata("vec_type_hint", llvm::MDNode::get(Context, AttrMDArgs));
657 }
658
659 if (const WorkGroupSizeHintAttr *A = FD->getAttr()) {
660 llvm::Metadata *AttrMDArgs[] = {
661 llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())),
662 llvm::ConstantAsMetadata::get(Builder.getInt32(A->getYDim())),
663 llvm::ConstantAsMetadata::get(Builder.getInt32(A->getZDim()))};
664 Fn->setMetadata("work_group_size_hint", llvm::MDNode::get(Context, AttrMDArgs));
665 }
666
667 if (const ReqdWorkGroupSizeAttr *A = FD->getAttr()) {
668 llvm::Metadata *AttrMDArgs[] = {
669 llvm::ConstantAsMetadata::get(Builder.getInt32(A->getXDim())),
670 llvm::ConstantAsMetadata::get(Builder.getInt32(A->getYDim())),
671 llvm::ConstantAsMetadata::get(Builder.getInt32(A->getZDim()))};
672 Fn->setMetadata("reqd_work_group_size", llvm::MDNode::get(Context, AttrMDArgs));
673 }
674
675 if (const OpenCLIntelReqdSubGroupSizeAttr *A =
676 FD->getAttr()) {
677 llvm::Metadata *AttrMDArgs[] = {
678 llvm::ConstantAsMetadata::get(Builder.getInt32(A->getSubGroupSize()))};
679 Fn->setMetadata("intel_reqd_sub_group_size",
680 llvm::MDNode::get(Context, AttrMDArgs));
681 }
682}
683
684
686 const Stmt *Body = nullptr;
687 if (auto *FD = dyn_cast_or_null(F))
689 else if (auto *OMD = dyn_cast_or_null(F))
690 Body = OMD->getBody();
691
692 if (auto *CS = dyn_cast_or_null(Body)) {
693 auto LastStmt = CS->body_rbegin();
694 if (LastStmt != CS->body_rend())
695 return isa(*LastStmt);
696 }
697 return false;
698}
699
701 if (SanOpts.has(SanitizerKind::Thread)) {
702 Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
703 Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
704 }
705}
706
707
708bool CodeGenFunction::requiresReturnValueCheck() const {
709 return requiresReturnValueNullabilityCheck() ||
712}
713
715 auto *MD = dyn_cast_or_null(D);
716 if (!MD || !MD->getDeclName().getAsIdentifierInfo() ||
717 !MD->getDeclName().getAsIdentifierInfo()->isStr("allocate") ||
718 (MD->getNumParams() != 1 && MD->getNumParams() != 2))
719 return false;
720
721 if (MD->parameters()[0]->getType().getCanonicalType() != Ctx.getSizeType())
722 return false;
723
724 if (MD->getNumParams() == 2) {
725 auto *PT = MD->parameters()[1]->getType()->getAs<PointerType>();
726 if (!PT || !PT->isVoidPointerType() ||
727 !PT->getPointeeType().isConstQualified())
728 return false;
729 }
730
731 return true;
732}
733
734bool CodeGenFunction::isInAllocaArgument(CGCXXABI &ABI, QualType Ty) {
737}
738
739bool CodeGenFunction::hasInAllocaArg(const CXXMethodDecl *MD) {
743 return isInAllocaArgument(CGM.getCXXABI(), P->getType());
744 });
745}
746
747
750 if (const auto *MD = dyn_cast(FD))
752 return nullptr;
754}
755
757 llvm::Function *Fn,
763 "Do not use a CodeGenFunction object for more than one function");
764
766
767 DidCallStackSave = false;
769 const FunctionDecl *FD = dyn_cast_or_null(D);
776 assert(CurFn->isDeclaration() && "Function already has body?");
777
778
779
780 do {
781#define SANITIZER(NAME, ID) \
782 if (SanOpts.empty()) \
783 break; \
784 if (SanOpts.has(SanitizerKind::ID)) \
785 if (CGM.isInNoSanitizeList(SanitizerKind::ID, Fn, Loc)) \
786 SanOpts.set(SanitizerKind::ID, false);
787
788#include "clang/Basic/Sanitizers.def"
789#undef SANITIZER
790 } while (false);
791
792 if (D) {
793 const bool SanitizeBounds = SanOpts.hasOneOf(SanitizerKind::Bounds);
795 bool NoSanitizeCoverage = false;
796
798 no_sanitize_mask |= Attr->getMask();
799
800 if (Attr->hasCoverage())
801 NoSanitizeCoverage = true;
802 }
803
804
806 if (no_sanitize_mask & SanitizerKind::Address)
807 SanOpts.set(SanitizerKind::KernelAddress, false);
808 if (no_sanitize_mask & SanitizerKind::KernelAddress)
809 SanOpts.set(SanitizerKind::Address, false);
810 if (no_sanitize_mask & SanitizerKind::HWAddress)
811 SanOpts.set(SanitizerKind::KernelHWAddress, false);
812 if (no_sanitize_mask & SanitizerKind::KernelHWAddress)
813 SanOpts.set(SanitizerKind::HWAddress, false);
814
815 if (SanitizeBounds && .hasOneOf(SanitizerKind::Bounds))
816 Fn->addFnAttr(llvm::Attribute::NoSanitizeBounds);
817
819 Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);
820
821
823 if (no_sanitize_mask & SanitizerKind::Thread)
824 Fn->addFnAttr("no_sanitize_thread");
825 }
826 }
827
829 CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
830 } else {
831
832 if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
833 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
835 SanitizerKind::KernelHWAddress))
836 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
837 if (SanOpts.has(SanitizerKind::MemtagStack))
838 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
839 if (SanOpts.has(SanitizerKind::Thread))
840 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
841 if (SanOpts.has(SanitizerKind::Type))
842 Fn->addFnAttr(llvm::Attribute::SanitizeType);
843 if (SanOpts.has(SanitizerKind::NumericalStability))
844 Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
845 if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
846 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
847 }
848 if (SanOpts.has(SanitizerKind::SafeStack))
849 Fn->addFnAttr(llvm::Attribute::SafeStack);
850 if (SanOpts.has(SanitizerKind::ShadowCallStack))
851 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
852
853 if (SanOpts.has(SanitizerKind::Realtime))
857 Fn->addFnAttr(llvm::Attribute::SanitizeRealtime);
859 Fn->addFnAttr(llvm::Attribute::SanitizeRealtimeBlocking);
860 }
861
862
863 if (SanOpts.hasOneOf(SanitizerKind::Fuzzer | SanitizerKind::FuzzerNoLink))
864 Fn->addFnAttr(llvm::Attribute::OptForFuzzing);
865
866
867
868 if (SanOpts.has(SanitizerKind::Thread)) {
869 if (const auto *OMD = dyn_cast_or_null(D)) {
870 const IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
871 if (OMD->getMethodFamily() == OMF_dealloc ||
873 (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) {
875 }
876 }
877 }
878
879
880
881
882 if (D && SanOpts.has(SanitizerKind::CFIUnrelatedCast)) {
885 }
886
887
888
889
890 if (D && SanOpts.has(SanitizerKind::Null))
891 if (FD && FD->getBody() &&
894
895
898 Fn->addFnAttr("ptrauth-returns");
900 Fn->addFnAttr("ptrauth-calls");
902 Fn->addFnAttr("ptrauth-auth-traps");
904 Fn->addFnAttr("ptrauth-indirect-gotos");
906 Fn->addFnAttr("aarch64-jump-table-hardening");
907
908
909 bool AlwaysXRayAttr = false;
910 if (const auto *XRayAttr = D ? D->getAttr() : nullptr) {
916 Fn->addFnAttr("function-instrument", "xray-always");
917 AlwaysXRayAttr = true;
918 }
919 if (XRayAttr->neverXRayInstrument())
920 Fn->addFnAttr("function-instrument", "xray-never");
921 if (const auto *LogArgs = D->getAttr())
923 Fn->addFnAttr("xray-log-args",
924 llvm::utostr(LogArgs->getArgumentCount()));
925 }
926 } else {
928 Fn->addFnAttr(
929 "xray-instruction-threshold",
931 }
932
935 Fn->addFnAttr("xray-ignore-loops");
936
939 Fn->addFnAttr("xray-skip-exit");
940
943 Fn->addFnAttr("xray-skip-entry");
944
946 if (FuncGroups > 1) {
948 CurFn->getName().bytes_end());
949 auto Group = crc32(FuncName) % FuncGroups;
951 !AlwaysXRayAttr)
952 Fn->addFnAttr("function-instrument", "xray-never");
953 }
954 }
955
959 Fn->addFnAttr(llvm::Attribute::SkipProfile);
960 break;
962 Fn->addFnAttr(llvm::Attribute::NoProfile);
963 break;
965 break;
966 }
967 }
968
969 unsigned Count, Offset;
970 if (const auto *Attr =
971 D ? D->getAttr() : nullptr) {
972 Count = Attr->getCount();
973 Offset = Attr->getOffset();
974 } else {
977 }
978 if (Count && Offset <= Count) {
979 Fn->addFnAttr("patchable-function-entry", std::to_string(Count - Offset));
980 if (Offset)
981 Fn->addFnAttr("patchable-function-prefix", std::to_string(Offset));
982 }
983
984
985
986
988 getContext().getTargetInfo().getTriple().isX86() &&
989 getContext().getTargetInfo().getTriple().getEnvironment() !=
990 llvm::Triple::CODE16)
991 Fn->addFnAttr("patchable-function", "prologue-short-redirect");
992
993
995 Fn->addFnAttr("no-jump-tables", "true");
996
997
999 Fn->addFnAttr("no-inline-line-tables");
1000
1001
1003 Fn->addFnAttr("profile-sample-accurate");
1004
1006 Fn->addFnAttr("use-sample-profile");
1007
1009 Fn->addFnAttr("cfi-canonical-jump-table");
1010
1012 Fn->addFnAttr(llvm::Attribute::NoProfile);
1013
1015 Fn->addFnAttr(llvm::Attribute::HybridPatchable);
1016
1017 if (D) {
1018
1019 if (auto *A = D->getAttr()) {
1020 switch (A->getThunkType()) {
1021 case FunctionReturnThunksAttr::Kind::Keep:
1022 break;
1023 case FunctionReturnThunksAttr::Kind::Extern:
1024 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
1025 break;
1026 }
1028 Fn->addFnAttr(llvm::Attribute::FnRetThunkExtern);
1029 }
1030
1033 getContext().getTargetInfo().getTriple().isSPIRV()) ||
1036
1037 EmitKernelMetadata(FD, Fn);
1038 }
1039
1040 if (FD && FD->hasAttr()) {
1041 Fn->setMetadata("clspv_libclc_builtin",
1043 }
1044
1045
1046
1047 if (FD && SanOpts.has(SanitizerKind::Function)) {
1049 llvm::LLVMContext &Ctx = Fn->getContext();
1050 llvm::MDBuilder MDB(Ctx);
1051 Fn->setMetadata(
1052 llvm::LLVMContext::MD_func_sanitize,
1053 MDB.createRTTIPointerPrologue(
1055 }
1056 }
1057
1058
1059
1060 if (SanOpts.has(SanitizerKind::NullabilityReturn)) {
1064 if (!(SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&
1066 RetValNullabilityPrecondition =
1068 }
1069 }
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085 if (FD &&
1089 Fn->addFnAttr(llvm::Attribute::NoRecurse);
1090
1092 llvm::fp::ExceptionBehavior FPExceptionBehavior =
1094 Builder.setDefaultConstrainedRounding(RM);
1095 Builder.setDefaultConstrainedExcept(FPExceptionBehavior);
1097 (!FD && (FPExceptionBehavior != llvm::fp::ebIgnore ||
1098 RM != llvm::RoundingMode::NearestTiesToEven))) {
1099 Builder.setIsFPConstrained(true);
1100 Fn->addFnAttr(llvm::Attribute::StrictFP);
1101 }
1102
1103
1104
1107 Fn->addFnAttr("stackrealign");
1108
1109
1110 if (FD && FD->isMain())
1111 Fn->removeFnAttr("zero-call-used-regs");
1112
1114
1115
1116
1117
1118 llvm::Value *Poison = llvm::PoisonValue::get(Int32Ty);
1120
1122
1123 Builder.SetInsertPoint(EntryBB);
1124
1125
1126
1127 if (requiresReturnValueCheck()) {
1130 ReturnLocation);
1131 }
1132
1133
1135
1136
1137
1138 DI->emitFunctionStart(GD, Loc, StartLoc,
1139 DI->getFunctionType(FD, RetTy, Args), CurFn,
1141 }
1142
1145 CurFn->addFnAttr("instrument-function-entry", "__cyg_profile_func_enter");
1147 CurFn->addFnAttr("instrument-function-entry-inlined",
1148 "__cyg_profile_func_enter");
1150 CurFn->addFnAttr("instrument-function-entry-inlined",
1151 "__cyg_profile_func_enter_bare");
1152 }
1153
1154
1155
1156
1157
1159
1160
1163 Fn->addFnAttr("fentry-call", "true");
1164 else {
1165 Fn->addFnAttr("instrument-function-entry-inlined",
1167 }
1171 << "-mnop-mcount" << "-mfentry";
1172 Fn->addFnAttr("mnop-mcount");
1173 }
1174
1178 << "-mrecord-mcount" << "-mfentry";
1179 Fn->addFnAttr("mrecord-mcount");
1180 }
1181 }
1182 }
1183
1185 if (getContext().getTargetInfo().getTriple().getArch() !=
1186 llvm::Triple::systemz)
1188 << "-mpacked-stack";
1189 Fn->addFnAttr("packed-stack");
1190 }
1191
1194 Fn->addFnAttr("warn-stack-size",
1196
1198
1200
1201
1203 ++NumReturnExprs;
1205
1206
1207 auto AI = CurFn->arg_begin();
1209 ++AI;
1218 }
1221
1223 llvm::Function::arg_iterator EI = CurFn->arg_end();
1224 --EI;
1227 llvm::Type *Ty =
1228 castllvm::GetElementPtrInst(Addr)->getResultElementType();
1233 } else {
1235
1236
1237
1238
1243 }
1244
1246
1248
1249
1252
1254
1255 if (FD->hasAttr()) {
1257 }
1259 }
1260
1262
1263 if (const CXXMethodDecl *MD = dyn_cast_if_present(D);
1265 bool IsInLambda =
1269 if (IsInLambda) {
1270
1274
1275
1276
1277
1278
1279
1282
1283
1284 CXXThisValue = ThisFieldLValue.getPointer(*this);
1285 } else {
1286
1287
1288 CXXThisValue =
1290 }
1291 }
1293 if (FD->hasCapturedVLAType()) {
1296 auto VAT = FD->getCapturedVLAType();
1297 VLASizeMap[VAT->getSizeExpr()] = ExprArg;
1298 }
1299 }
1301
1302
1303
1304 CXXThisValue = CXXABIThisValue;
1305 }
1306
1307
1308 if (CXXABIThisValue) {
1310 SkippedChecks.set(SanitizerKind::ObjectSize, true);
1312
1313
1314
1315
1317 SkippedChecks.set(SanitizerKind::Null, true);
1318
1321 Loc, CXXABIThisValue, ThisTy, CXXABIThisAlignment, SkippedChecks);
1322 }
1323 }
1324
1325
1326
1327
1328 if (!FD || !FD->hasAttr()) {
1329 for (const VarDecl *VD : Args) {
1330
1331
1332
1334 if (const ParmVarDecl *PVD = dyn_cast(VD))
1335 Ty = PVD->getOriginalType();
1336 else
1337 Ty = VD->getType();
1338
1341 }
1342 }
1343
1345 DI->EmitLocation(Builder, StartLoc);
1346
1347
1349 if (const auto *VecWidth = CurFuncDecl->getAttr())
1350 LargestVectorWidth = VecWidth->getVectorWidth();
1351
1354}
1355
1359 if (const CompoundStmt *S = dyn_cast(Body))
1361 else
1363}
1364
1365
1366
1367
1368
1370 const Stmt *S) {
1371 llvm::BasicBlock *SkipCountBB = nullptr;
1372
1373
1376
1377
1378
1381 }
1386 if (SkipCountBB)
1388}
1389
1390
1391
1392
1394
1395
1396 if (F->isInterposable()) return;
1397
1398 for (llvm::BasicBlock &BB : *F)
1399 for (llvm::Instruction &I : BB)
1400 if (I.mayThrow())
1401 return;
1402
1403 F->setDoesNotThrow();
1404}
1405
1410
1411 const CXXMethodDecl *MD = dyn_cast(FD);
1418 }
1419
1420
1421
1422
1423 bool PassedParams = true;
1424 if (const CXXConstructorDecl *CD = dyn_cast(FD))
1425 if (auto Inherited = CD->getInheritedConstructor())
1426 PassedParams =
1428
1429 if (PassedParams) {
1430 for (auto *Param : FD->parameters()) {
1431 Args.push_back(Param);
1432 if (!Param->hasAttr())
1433 continue;
1434
1436 getContext(), Param->getDeclContext(), Param->getLocation(),
1438 SizeArguments[Param] = Implicit;
1440 }
1441 }
1442
1443 if (MD && (isa(MD) || isa(MD)))
1445
1446 return ResTy;
1447}
1448
1451 assert(Fn && "generating code for null Function");
1454
1457
1459
1461
1462
1463
1464 std::string FDInlineName = (Fn->getName() + ".inline").str();
1465 llvm::Module *M = Fn->getParent();
1466 llvm::Function *Clone = M->getFunction(FDInlineName);
1467 if (!Clone) {
1468 Clone = llvm::Function::Create(Fn->getFunctionType(),
1469 llvm::GlobalValue::InternalLinkage,
1470 Fn->getAddressSpace(), FDInlineName, M);
1471 Clone->addFnAttr(llvm::Attribute::AlwaysInline);
1472 }
1473 Fn->setLinkage(llvm::GlobalValue::ExternalLinkage);
1474 Fn = Clone;
1475 } else {
1476
1477
1478
1479
1480
1483 if (LLVM_UNLIKELY(PD->isInlineBuiltinDeclaration())) {
1484 std::string FDInlineName = (Fn->getName() + ".inline").str();
1485 llvm::Module *M = Fn->getParent();
1486 if (llvm::Function *Clone = M->getFunction(FDInlineName)) {
1487 Clone->replaceAllUsesWith(Fn);
1488 Clone->eraseFromParent();
1489 }
1490 break;
1491 }
1492 }
1493 }
1494
1495
1496 if (FD->hasAttr()) {
1497
1498
1499 Fn->setSubprogram(nullptr);
1500
1501 DebugInfo = nullptr;
1502 }
1503
1504
1505
1509 else
1511 CurEHLocation = BodyRange.getEnd();
1512
1513
1514
1515
1516
1517
1519
1520
1521
1523 if (SpecDecl->hasBody(SpecDecl))
1524 Loc = SpecDecl->getLocation();
1525
1527
1528 if (Body) {
1529
1530 if (isa(Body))
1531 ShouldEmitLifetimeMarkers = true;
1532
1533
1534
1535 if (ShouldEmitLifetimeMarkers)
1537 }
1538
1539
1541
1542
1543 if (Body && isa_and_nonnull(Body))
1545
1546
1547
1548
1549
1551 CurFn->addFnAttr(llvm::Attribute::MustProgress);
1552
1553
1555 if (isa(FD))
1557 else if (isa(FD))
1561 FD->hasAttr())
1563 else if (isa(FD) &&
1564 cast(FD)->isLambdaStaticInvoker()) {
1565
1566
1568 } else if (isa(FD) &&
1571 cast(FD)->getParent()->getLambdaStaticInvoker() &&
1572 hasInAllocaArg(cast(FD))) {
1573
1574
1575
1576
1577
1579 } else if (FD->isDefaulted() && isa(FD) &&
1580 (cast(FD)->isCopyAssignmentOperator() ||
1581 cast(FD)->isMoveAssignmentOperator())) {
1582
1583
1585 } else if (Body) {
1587 } else
1588 llvm_unreachable("no definition for emitted function");
1589
1590
1591
1592
1593
1594
1595
1598 bool ShouldEmitUnreachable =
1601 if (SanOpts.has(SanitizerKind::Return)) {
1602 SanitizerScope SanScope(this);
1603 llvm::Value *IsFalse = Builder.getFalse();
1604 EmitCheck(std::make_pair(IsFalse, SanitizerKind::SO_Return),
1605 SanitizerHandler::MissingReturn,
1607 } else if (ShouldEmitUnreachable) {
1610 }
1611 if (SanOpts.has(SanitizerKind::Return) || ShouldEmitUnreachable) {
1612 Builder.CreateUnreachable();
1613 Builder.ClearInsertionPoint();
1614 }
1615 }
1616
1617
1619
1621
1622
1623
1624 if (->doesNotThrow())
1626}
1627
1628
1629
1630
1632
1633 if (!S) return false;
1634
1635
1636
1637
1638
1639
1640 if (isa(S))
1641 return true;
1642
1643
1644
1645 if (isa(S) && !IgnoreCaseStmts)
1646 return true;
1647
1648
1649 if (isa(S))
1650 IgnoreCaseStmts = true;
1651
1652
1653 for (const Stmt *SubStmt : S->children())
1655 return true;
1656
1657 return false;
1658}
1659
1660
1661
1662
1664
1665 if (!S) return false;
1666
1667
1668
1669 if (isa(S) || isa(S) || isa(S) ||
1670 isa(S))
1671 return false;
1672
1673 if (isa(S))
1674 return true;
1675
1676
1677 for (const Stmt *SubStmt : S->children())
1679 return true;
1680
1681 return false;
1682}
1683
1685 if (!S) return false;
1686
1687
1688
1689
1690
1691 if (isa(S) || isa(S) || isa(S) ||
1692 isa(S) || isa(S) || isa(S) ||
1693 isa(S) || isa(S) ||
1694 isa(S) || isa(S))
1695 return false;
1696
1697 if (isa(S))
1698 return true;
1699
1700 for (const Stmt *SubStmt : S->children())
1702 return true;
1703
1704 return false;
1705}
1706
1707
1708
1709
1711 bool &ResultBool,
1712 bool AllowLabels) {
1713
1714
1715
1718 return false;
1719
1720 llvm::APSInt ResultInt;
1722 return false;
1723
1724 ResultBool = ResultInt.getBoolValue();
1725 return true;
1726}
1727
1728
1729
1730
1732 llvm::APSInt &ResultInt,
1733 bool AllowLabels) {
1734
1735
1738 return false;
1739
1740 llvm::APSInt Int = Result.Val.getInt();
1742 return false;
1743
1745 ResultInt = Int;
1746 return true;
1747}
1748
1749
1751 while (const UnaryOperator *Op = dyn_cast(C->IgnoreParens())) {
1752 if (Op->getOpcode() != UO_LNot)
1753 break;
1754 C = Op->getSubExpr();
1755 }
1756 return C->IgnoreParens();
1757}
1758
1759
1760
1764}
1765
1766
1767
1768
1769
1772 llvm::BasicBlock *FalseBlock, uint64_t TrueCount ,
1774
1778
1779 const Stmt *CntrStmt = (CntrIdx ? CntrIdx : Cond);
1780
1781 llvm::BasicBlock *ThenBlock = nullptr;
1782 llvm::BasicBlock *ElseBlock = nullptr;
1783 llvm::BasicBlock *NextBlock = nullptr;
1784
1785
1786 llvm::BasicBlock *CounterIncrBlock = createBasicBlock("lop.rhscnt");
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800 if (LOp == BO_LAnd) {
1801 ThenBlock = CounterIncrBlock;
1802 ElseBlock = FalseBlock;
1803 NextBlock = TrueBlock;
1804 }
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818 else if (LOp == BO_LOr) {
1819 ThenBlock = TrueBlock;
1820 ElseBlock = CounterIncrBlock;
1821 NextBlock = FalseBlock;
1822 } else {
1823 llvm_unreachable("Expected Opcode must be that of a Logical Operator");
1824 }
1825
1826
1828
1829
1831
1832
1834
1835
1837}
1838
1839
1840
1841
1842
1843
1844
1845
1847 const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock,
1850
1851 if (const BinaryOperator *CondBOp = dyn_cast(Cond)) {
1852
1853 if (CondBOp->getOpcode() == BO_LAnd) {
1855
1856
1857
1858 bool ConstantBool = false;
1860 ConstantBool) {
1861
1864 FalseBlock, TrueCount, LH);
1866 return;
1867 }
1868
1869
1870
1872 ConstantBool) {
1873
1875 FalseBlock, TrueCount, LH, CondBOp);
1877 return;
1878 }
1879
1880
1881
1882 llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true");
1883
1884
1886
1887 ConditionalEvaluation eval(*this);
1888 {
1890
1891
1892
1896 }
1897
1900
1901
1902 eval.begin(*this);
1904 FalseBlock, TrueCount, LH);
1905 eval.end(*this);
1907 return;
1908 }
1909
1910 if (CondBOp->getOpcode() == BO_LOr) {
1912
1913
1914
1915 bool ConstantBool = false;
1917 !ConstantBool) {
1918
1921 FalseBlock, TrueCount, LH);
1923 return;
1924 }
1925
1926
1927
1929 !ConstantBool) {
1930
1932 FalseBlock, TrueCount, LH, CondBOp);
1934 return;
1935 }
1936
1937
1938 llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false");
1939
1940
1941
1944 uint64_t RHSCount = TrueCount - LHSCount;
1945
1946 ConditionalEvaluation eval(*this);
1947 {
1948
1949
1950
1955 }
1956
1959
1960
1961 eval.begin(*this);
1963 RHSCount, LH);
1964
1965 eval.end(*this);
1967 return;
1968 }
1969 }
1970
1971 if (const UnaryOperator *CondUOp = dyn_cast(Cond)) {
1972
1973
1974
1975
1979 if (CondUOp->getOpcode() == UO_LNot && !MCDCCondition) {
1980
1982
1984
1986 FalseCount, LH);
1987 }
1988 }
1989
1990 if (const ConditionalOperator *CondOp = dyn_cast(Cond)) {
1991
1993 llvm::BasicBlock *RHSBlock = createBasicBlock("cond.false");
1994
1995
1996
1997 ConditionalEvaluation cond(*this);
2000
2001
2002
2003
2004
2005
2006 uint64_t LHSScaledTrueCount = 0;
2007 if (TrueCount) {
2008 double LHSRatio =
2010 LHSScaledTrueCount = TrueCount * LHSRatio;
2011 }
2012
2013 cond.begin(*this);
2016 {
2019 LHSScaledTrueCount, LH, CondOp);
2020 }
2021 cond.end(*this);
2022
2023 cond.begin(*this);
2026 TrueCount - LHSScaledTrueCount, LH, CondOp);
2027 cond.end(*this);
2028
2029 return;
2030 }
2031
2032 if (const CXXThrowExpr *Throw = dyn_cast(Cond)) {
2033
2034
2035
2036
2037
2039 return;
2040 }
2041
2042
2043 llvm::Value *CondV;
2044 {
2047 }
2048
2049
2050
2052 const Expr *MCDCBaseExpr = Cond;
2053
2054
2055
2056
2057
2058 if (ConditionalOp)
2059 MCDCBaseExpr = ConditionalOp;
2060
2062 }
2063
2064 llvm::MDNode *Weights = nullptr;
2065 llvm::MDNode *Unpredictable = nullptr;
2066
2067
2068
2069
2072 auto *FD = dyn_cast_or_null(Call->getCalleeDecl());
2073 if (FD && FD->getBuiltinID() == Builtin::BI__builtin_unpredictable) {
2075 Unpredictable = MDHelper.createUnpredictable();
2076 }
2077 }
2078
2079
2080
2081 llvm::Value *NewCondV = emitCondLikelihoodViaExpectIntrinsic(CondV, LH);
2082 if (CondV != NewCondV)
2083 CondV = NewCondV;
2084 else {
2085
2087 Weights = createProfileWeights(TrueCount, CurrentCount - TrueCount);
2088 }
2089
2090 llvm::Instruction *BrInst = Builder.CreateCondBr(CondV, TrueBlock, FalseBlock,
2091 Weights, Unpredictable);
2093 case HLSLControlFlowHintAttr::Microsoft_branch:
2094 case HLSLControlFlowHintAttr::Microsoft_flatten: {
2096
2097 llvm::ConstantInt *BranchHintConstant =
2099 HLSLControlFlowHintAttr::Spelling::Microsoft_branch
2100 ? llvm::ConstantInt::get(CGM.Int32Ty, 1)
2102
2104 {MDHelper.createString("hlsl.controlflow.hint"),
2105 MDHelper.createConstant(BranchHintConstant)});
2106 BrInst->setMetadata("hlsl.controlflow.hint",
2108 break;
2109 }
2110
2111 case HLSLControlFlowHintAttr::SpellingNotCalculated:
2112 break;
2113 }
2114}
2115
2116
2117
2120}
2121
2122
2123
2124
2125
2126
2127
2128
2131 llvm::Value *sizeInChars) {
2133
2135 llvm::Value *baseSizeInChars
2137
2141 sizeInChars, "vla.end");
2142
2143 llvm::BasicBlock *originBB = CGF.Builder.GetInsertBlock();
2144 llvm::BasicBlock *loopBB = CGF.createBasicBlock("vla-init.loop");
2145 llvm::BasicBlock *contBB = CGF.createBasicBlock("vla-init.cont");
2146
2147
2148
2150
2151 llvm::PHINode *cur = Builder.CreatePHI(begin.getType(), 2, "vla.cur");
2152 cur->addIncoming(begin.emitRawPointer(CGF), originBB);
2153
2156
2157
2159 false);
2160
2161
2162 llvm::Value *next =
2164
2165
2166 llvm::Value *done = Builder.CreateICmpEQ(next, end, "vla-init.isdone");
2167 Builder.CreateCondBr(done, contBB, loopBB);
2168 cur->addIncoming(next, loopBB);
2169
2171}
2172
2173void
2175
2178 if (cast(RT->getDecl())->isEmpty())
2179 return;
2180 }
2181 }
2182
2185
2186
2188
2189 llvm::Value *SizeVal;
2191
2192
2193 if (size.isZero()) {
2194
2196 dyn_cast_or_null(
2199 SizeVal = VlaSize.NumElts;
2201 if (!eltSize.isOne())
2203 vla = vlaType;
2204 } else {
2205 return;
2206 }
2207 } else {
2209 vla = nullptr;
2210 }
2211
2212
2213
2214
2215
2217
2219
2221
2222 llvm::GlobalVariable *NullVariable =
2223 new llvm::GlobalVariable(CGM.getModule(), NullConstant->getType(),
2224 true,
2225 llvm::GlobalVariable::PrivateLinkage,
2226 NullConstant, Twine());
2228 NullVariable->setAlignment(NullAlign.getAsAlign());
2229 Address SrcPtr(NullVariable, Builder.getInt8Ty(), NullAlign);
2230
2231 if (vla) return emitNonZeroVLAInit(*this, Ty, DestPtr, SrcPtr, SizeVal);
2232
2233
2235 return;
2236 }
2237
2238
2239
2240
2242}
2243
2245
2246 if (!IndirectBranch)
2248
2250
2251
2252 IndirectBranch->addDestination(BB);
2253 return llvm::BlockAddress::get(CurFn, BB);
2254}
2255
2257
2258 if (IndirectBranch) return IndirectBranch->getParent();
2259
2261
2262
2263 llvm::Value *DestVal = TmpBuilder.CreatePHI(Int8PtrTy, 0,
2264 "indirect.goto.dest");
2265
2266
2267 IndirectBranch = TmpBuilder.CreateIndirectBr(DestVal);
2268 return IndirectBranch->getParent();
2269}
2270
2271
2272
2277
2278
2279
2280 llvm::Value *numVLAElements = nullptr;
2281 if (isa(arrayType)) {
2283
2284
2285
2286 do {
2289
2290
2292 baseType = elementType;
2293 return numVLAElements;
2294 }
2295 } while (isa(arrayType));
2296
2297
2298
2299 }
2300
2301
2302
2303
2305
2306
2307 llvm::ConstantInt *zero = Builder.getInt32(0);
2308 gepIndices.push_back(zero);
2309
2312
2313 llvm::ArrayType *llvmArrayType =
2315 while (llvmArrayType) {
2316 assert(isa(arrayType));
2317 assert(cast(arrayType)->getZExtSize() ==
2318 llvmArrayType->getNumElements());
2319
2320 gepIndices.push_back(zero);
2321 countFromCLAs *= llvmArrayType->getNumElements();
2322 eltType = arrayType->getElementType();
2323
2324 llvmArrayType =
2325 dyn_castllvm::ArrayType(llvmArrayType->getElementType());
2327 assert((!llvmArrayType || arrayType) &&
2328 "LLVM and Clang types are out-of-synch");
2329 }
2330
2332
2333
2334
2336 countFromCLAs *= cast(arrayType)->getZExtSize();
2337 eltType = arrayType->getElementType();
2339 }
2340
2341 llvm::Type *baseType = ConvertType(eltType);
2343 } else {
2344
2347 gepIndices, "array.begin"),
2349 }
2350
2351 baseType = eltType;
2352
2353 llvm::Value *numElements
2354 = llvm::ConstantInt::get(SizeTy, countFromCLAs);
2355
2356
2357 if (numVLAElements)
2358 numElements = Builder.CreateNUWMul(numVLAElements, numElements);
2359
2360 return numElements;
2361}
2362
2365 assert(vla && "type was not a variable array type!");
2367}
2368
2369CodeGenFunction::VlaSizePair
2371
2372 llvm::Value *numElements = nullptr;
2373
2375 do {
2376 elementType = type->getElementType();
2377 llvm::Value *vlaSize = VLASizeMap[type->getSizeExpr()];
2378 assert(vlaSize && "no size for VLA!");
2379 assert(vlaSize->getType() == SizeTy);
2380
2381 if (!numElements) {
2382 numElements = vlaSize;
2383 } else {
2384
2385
2386 numElements = Builder.CreateNUWMul(numElements, vlaSize);
2387 }
2388 } while ((type = getContext().getAsVariableArrayType(elementType)));
2389
2390 return { numElements, elementType };
2391}
2392
2393CodeGenFunction::VlaSizePair
2396 assert(vla && "type was not a variable array type!");
2398}
2399
2400CodeGenFunction::VlaSizePair
2402 llvm::Value *VlaSize = VLASizeMap[Vla->getSizeExpr()];
2403 assert(VlaSize && "no size for VLA!");
2404 assert(VlaSize->getType() == SizeTy);
2406}
2407
2409 assert(type->isVariablyModifiedType() &&
2410 "Must pass variably modified type to EmitVLASizes!");
2411
2413
2414
2415
2416 do {
2417 assert(type->isVariablyModifiedType());
2418
2419 const Type *ty = type.getTypePtr();
2421
2422#define TYPE(Class, Base)
2423#define ABSTRACT_TYPE(Class, Base)
2424#define NON_CANONICAL_TYPE(Class, Base)
2425#define DEPENDENT_TYPE(Class, Base) case Type::Class:
2426#define NON_CANONICAL_UNLESS_DEPENDENT_TYPE(Class, Base)
2427#include "clang/AST/TypeNodes.inc"
2428 llvm_unreachable("unexpected dependent type!");
2429
2430
2431 case Type::Builtin:
2432 case Type::Complex:
2433 case Type::Vector:
2434 case Type::ExtVector:
2435 case Type::ConstantMatrix:
2436 case Type::Record:
2437 case Type::Enum:
2438 case Type::Using:
2439 case Type::TemplateSpecialization:
2440 case Type::ObjCTypeParam:
2441 case Type::ObjCObject:
2442 case Type::ObjCInterface:
2443 case Type::ObjCObjectPointer:
2444 case Type::BitInt:
2445 llvm_unreachable("type class is never variably-modified!");
2446
2447 case Type::Elaborated:
2448 type = cast(ty)->getNamedType();
2449 break;
2450
2451 case Type::Adjusted:
2452 type = cast(ty)->getAdjustedType();
2453 break;
2454
2455 case Type::Decayed:
2456 type = cast(ty)->getPointeeType();
2457 break;
2458
2459 case Type::Pointer:
2460 type = cast(ty)->getPointeeType();
2461 break;
2462
2463 case Type::BlockPointer:
2464 type = cast(ty)->getPointeeType();
2465 break;
2466
2467 case Type::LValueReference:
2468 case Type::RValueReference:
2469 type = cast(ty)->getPointeeType();
2470 break;
2471
2472 case Type::MemberPointer:
2473 type = cast(ty)->getPointeeType();
2474 break;
2475
2476 case Type::ArrayParameter:
2477 case Type::ConstantArray:
2478 case Type::IncompleteArray:
2479
2480 type = cast(ty)->getElementType();
2481 break;
2482
2483 case Type::VariableArray: {
2484
2486
2487
2488
2490
2491
2492 llvm::Value *&entry = VLASizeMap[sizeExpr];
2493 if (!entry) {
2495
2496
2497
2498
2499
2500 if (SanOpts.has(SanitizerKind::VLABound)) {
2501 SanitizerScope SanScope(this);
2502 llvm::Value *Zero = llvm::Constant::getNullValue(size->getType());
2504 llvm::Value *CheckCondition =
2506 ? Builder.CreateICmpSGT(size, Zero)
2507 : Builder.CreateICmpUGT(size, Zero);
2508 llvm::Constant *StaticArgs[] = {
2512 std::make_pair(CheckCondition, SanitizerKind::SO_VLABound),
2513 SanitizerHandler::VLABoundNotPositive, StaticArgs, size);
2514 }
2515
2516
2517
2518
2519 entry = Builder.CreateIntCast(size, SizeTy, false);
2520 }
2521 }
2523 break;
2524 }
2525
2526 case Type::FunctionProto:
2527 case Type::FunctionNoProto:
2528 type = cast(ty)->getReturnType();
2529 break;
2530
2531 case Type::Paren:
2532 case Type::TypeOf:
2533 case Type::UnaryTransform:
2534 case Type::Attributed:
2535 case Type::BTFTagAttributed:
2536 case Type::HLSLAttributedResource:
2537 case Type::SubstTemplateTypeParm:
2538 case Type::MacroQualified:
2539 case Type::CountAttributed:
2540
2542 break;
2543
2544 case Type::Typedef:
2545 case Type::Decltype:
2546 case Type::Auto:
2547 case Type::DeducedTemplateSpecialization:
2548 case Type::PackIndexing:
2549
2550 return;
2551
2552 case Type::TypeOfExpr:
2553
2554 EmitIgnoredExpr(cast(ty)->getUnderlyingExpr());
2555 return;
2556
2557 case Type::Atomic:
2558 type = cast(ty)->getValueType();
2559 break;
2560
2561 case Type::Pipe:
2562 type = cast(ty)->getElementType();
2563 break;
2564 }
2565 } while (type->isVariablyModifiedType());
2566}
2567
2569 if (getContext().getBuiltinVaListType()->isArrayType())
2572}
2573
2576}
2577
2580 assert(Init.hasValue() && "Invalid DeclRefExpr initializer!");
2583 Dbg->EmitGlobalVariable(E->getDecl(), Init);
2584}
2585
2586CodeGenFunction::PeepholeProtection
2588
2589
2590
2591
2592 if (!rvalue.isScalar()) return PeepholeProtection();
2594 if (!isallvm::ZExtInst(value)) return PeepholeProtection();
2595
2596
2598 llvm::Instruction *inst = new llvm::BitCastInst(value, value->getType(), "",
2599 Builder.GetInsertBlock());
2600
2601 PeepholeProtection protection;
2602 protection.Inst = inst;
2603 return protection;
2604}
2605
2607 if (!protection.Inst) return;
2608
2609
2610 protection.Inst->eraseFromParent();
2611}
2612
2616 llvm::Value *Alignment,
2617 llvm::Value *OffsetValue) {
2618 if (Alignment->getType() != IntPtrTy)
2619 Alignment =
2620 Builder.CreateIntCast(Alignment, IntPtrTy, false, "casted.align");
2621 if (OffsetValue && OffsetValue->getType() != IntPtrTy)
2622 OffsetValue =
2623 Builder.CreateIntCast(OffsetValue, IntPtrTy, true, "casted.offset");
2624 llvm::Value *TheCheck = nullptr;
2625 if (SanOpts.has(SanitizerKind::Alignment)) {
2626 llvm::Value *PtrIntValue =
2628
2629 if (OffsetValue) {
2630 bool IsOffsetZero = false;
2631 if (const auto *CI = dyn_castllvm::ConstantInt(OffsetValue))
2632 IsOffsetZero = CI->isZero();
2633
2634 if (!IsOffsetZero)
2635 PtrIntValue = Builder.CreateSub(PtrIntValue, OffsetValue, "offsetptr");
2636 }
2637
2638 llvm::Value *Zero = llvm::ConstantInt::get(IntPtrTy, 0);
2639 llvm::Value *Mask =
2640 Builder.CreateSub(Alignment, llvm::ConstantInt::get(IntPtrTy, 1));
2641 llvm::Value *MaskedPtr = Builder.CreateAnd(PtrIntValue, Mask, "maskedptr");
2642 TheCheck = Builder.CreateICmpEQ(MaskedPtr, Zero, "maskcond");
2643 }
2644 llvm::Instruction *Assumption = Builder.CreateAlignmentAssumption(
2646
2647 if (.has(SanitizerKind::Alignment))
2648 return;
2650 OffsetValue, TheCheck, Assumption);
2651}
2652
2656 llvm::Value *Alignment,
2657 llvm::Value *OffsetValue) {
2660
2662 OffsetValue);
2663}
2664
2666 llvm::Value *AnnotatedVal,
2667 StringRef AnnotationStr,
2669 const AnnotateAttr *Attr) {
2671 AnnotatedVal,
2675 };
2678 return Builder.CreateCall(AnnotationFn, Args);
2679}
2680
2682 assert(D->hasAttr() && "no annotate attribute");
2685 {V->getType(), CGM.ConstGlobalsPtrTy}),
2687}
2688
2691 assert(D->hasAttr() && "no annotate attribute");
2693 llvm::Type *VTy = V->getType();
2694 auto *PTy = dyn_castllvm::PointerType(VTy);
2695 unsigned AS = PTy ? PTy->getAddressSpace() : 0;
2696 llvm::PointerType *IntrinTy =
2698 llvm::Function *F = CGM.getIntrinsic(llvm::Intrinsic::ptr_annotation,
2700
2701 for (const auto *I : D->specific_attrs()) {
2702
2703
2704
2705 if (VTy != IntrinTy)
2706 V = Builder.CreateBitCast(V, IntrinTy);
2708 V = Builder.CreateBitCast(V, VTy);
2709 }
2710
2712}
2713
2715
2717 : CGF(CGF) {
2720}
2721
2723 CGF->IsSanitizerScope = false;
2724}
2725
2727 const llvm::Twine &Name,
2728 llvm::BasicBlock::iterator InsertPt) const {
2731 I->setNoSanitizeMetadata();
2732}
2733
2735 llvm::Instruction *I, const llvm::Twine &Name,
2736 llvm::BasicBlock::iterator InsertPt) const {
2737 llvm::IRBuilderDefaultInserter::InsertHelper(I, Name, InsertPt);
2738 if (CGF)
2739 CGF->InsertHelper(I, Name, InsertPt);
2740}
2741
2742
2743
2746
2747
2749 unsigned BuiltinID = TargetDecl->getBuiltinID();
2750 if (BuiltinID == X86::BI__builtin_ia32_cmpps ||
2751 BuiltinID == X86::BI__builtin_ia32_cmpss ||
2752 BuiltinID == X86::BI__builtin_ia32_cmppd ||
2753 BuiltinID == X86::BI__builtin_ia32_cmpsd) {
2755 llvm::StringMap TargetFetureMap;
2757 llvm::APSInt Result =
2759 if (Result.getSExtValue() > 7 && !TargetFetureMap.lookup("avx"))
2762 }
2763 }
2765}
2766
2767
2768
2771
2772 if (!TargetDecl)
2773 return;
2774
2775
2776
2778 if (!FD)
2779 return;
2780
2781
2782
2783
2784 unsigned BuiltinID = TargetDecl->getBuiltinID();
2785 std::string MissingFeature;
2786 llvm::StringMap CallerFeatureMap;
2788
2789
2790
2791
2793 if (BuiltinID) {
2796 FeatureList, CallerFeatureMap) && !IsHipStdPar) {
2799 << FeatureList;
2800 }
2802 TargetDecl->hasAttr()) {
2803
2804
2805 const TargetAttr *TD = TargetDecl->getAttr();
2808
2810 llvm::StringMap CalleeFeatureMap;
2812
2813 for (const auto &F : ParsedAttr.Features) {
2814 if (F[0] == '+' && CalleeFeatureMap.lookup(F.substr(1)))
2815 ReqFeatures.push_back(StringRef(F).substr(1));
2816 }
2817
2818 for (const auto &F : CalleeFeatureMap) {
2819
2820 if (F.getValue())
2821 ReqFeatures.push_back(F.getKey());
2822 }
2823 if (!llvm::all_of(ReqFeatures, [&](StringRef Feature) {
2824 if (!CallerFeatureMap.lookup(Feature)) {
2825 MissingFeature = Feature.str();
2826 return false;
2827 }
2828 return true;
2829 }) && !IsHipStdPar)
2833 llvm::StringMap CalleeFeatureMap;
2835
2836 for (const auto &F : CalleeFeatureMap) {
2837 if (F.getValue() && (!CallerFeatureMap.lookup(F.getKey()) ||
2838 !CallerFeatureMap.find(F.getKey())->getValue()) &&
2839 !IsHipStdPar)
2842 }
2843 }
2844}
2845
2848 return;
2849
2850 llvm::IRBuilder<> IRB(Builder.GetInsertBlock(), Builder.GetInsertPoint());
2851 IRB.SetCurrentDebugLocation(Builder.getCurrentDebugLocation());
2853}
2854
2858 Callee.getAbstractInfo().getCalleeFunctionProtoType();
2859 if (FP)
2861}
2862
2863llvm::Value *
2864CodeGenFunction::FormAArch64ResolverCondition(const FMVResolverOption &RO) {
2865 return RO.Features.empty() ? nullptr : EmitAArch64CpuSupports(RO.Features);
2866}
2867
2868llvm::Value *
2869CodeGenFunction::FormX86ResolverCondition(const FMVResolverOption &RO) {
2870 llvm::Value *Condition = nullptr;
2871
2872 if (RO.Architecture) {
2873 StringRef Arch = *RO.Architecture;
2874
2875
2876 if (Arch.starts_with("x86-64"))
2877 Condition = EmitX86CpuSupports({Arch});
2878 else
2880 }
2881
2882 if (!RO.Features.empty()) {
2883 llvm::Value *FeatureCond = EmitX86CpuSupports(RO.Features);
2886 }
2888}
2889
2891 llvm::Function *Resolver,
2893 llvm::Function *FuncToReturn,
2894 bool SupportsIFunc) {
2895 if (SupportsIFunc) {
2896 Builder.CreateRet(FuncToReturn);
2897 return;
2898 }
2899
2901 llvm::make_pointer_range(Resolver->args()));
2902
2903 llvm::CallInst *Result = Builder.CreateCall(FuncToReturn, Args);
2904 Result->setTailCallKind(llvm::CallInst::TCK_MustTail);
2905
2906 if (Resolver->getReturnType()->isVoidTy())
2907 Builder.CreateRetVoid();
2908 else
2910}
2911
2914
2915 llvm::Triple::ArchType ArchType =
2917
2918 switch (ArchType) {
2919 case llvm::Triple::x86:
2920 case llvm::Triple::x86_64:
2922 return;
2923 case llvm::Triple::aarch64:
2925 return;
2926 case llvm::Triple::riscv32:
2927 case llvm::Triple::riscv64:
2929 return;
2930
2931 default:
2932 assert(false && "Only implemented for x86, AArch64 and RISC-V targets");
2933 }
2934}
2935
2938
2939 if (getContext().getTargetInfo().getTriple().getOS() !=
2940 llvm::Triple::OSType::Linux) {
2942 return;
2943 }
2944
2945 llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
2946 Builder.SetInsertPoint(CurBlock);
2948
2950 bool HasDefault = false;
2951 unsigned DefaultIndex = 0;
2952
2953
2954 for (unsigned Index = 0; Index < Options.size(); Index++) {
2955
2956 if (Options[Index].Features.empty()) {
2957 HasDefault = true;
2958 DefaultIndex = Index;
2959 continue;
2960 }
2961
2962 Builder.SetInsertPoint(CurBlock);
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2987
2988 for (StringRef Feat : Options[Index].Features) {
2989 std::vectorstd::string FeatStr =
2991
2992 assert(FeatStr.size() == 1 && "Feature string not delimited");
2993
2994 std::string &CurrFeat = FeatStr.front();
2995 if (CurrFeat[0] == '+')
2996 TargetAttrFeats.push_back(CurrFeat.substr(1));
2997 }
2998
2999 if (TargetAttrFeats.empty())
3000 continue;
3001
3002 for (std::string &Feat : TargetAttrFeats)
3003 CurrTargetAttrFeats.push_back(Feat);
3004
3005 Builder.SetInsertPoint(CurBlock);
3007
3008 llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);
3009 CGBuilderTy RetBuilder(*this, RetBlock);
3011 Options[Index].Function, SupportsIFunc);
3012 llvm::BasicBlock *ElseBlock = createBasicBlock("resolver_else", Resolver);
3013
3014 Builder.SetInsertPoint(CurBlock);
3015 Builder.CreateCondBr(FeatsCondition, RetBlock, ElseBlock);
3016
3017 CurBlock = ElseBlock;
3018 }
3019
3020
3021 if (HasDefault) {
3022 Builder.SetInsertPoint(CurBlock);
3024 CGM, Resolver, Builder, Options[DefaultIndex].Function, SupportsIFunc);
3025 return;
3026 }
3027
3028
3029 Builder.SetInsertPoint(CurBlock);
3030 llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
3031 TrapCall->setDoesNotReturn();
3032 TrapCall->setDoesNotThrow();
3033 Builder.CreateUnreachable();
3034 Builder.ClearInsertionPoint();
3035}
3036
3039 assert(!Options.empty() && "No multiversion resolver options found");
3040 assert(Options.back().Features.size() == 0 && "Default case must be last");
3042 assert(SupportsIFunc &&
3043 "Multiversion resolver requires target IFUNC support");
3044 bool AArch64CpuInitialized = false;
3045 llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
3046
3047 for (const FMVResolverOption &RO : Options) {
3048 Builder.SetInsertPoint(CurBlock);
3049 llvm::Value *Condition = FormAArch64ResolverCondition(RO);
3050
3051
3054 SupportsIFunc);
3055 return;
3056 }
3057
3058 if (!AArch64CpuInitialized) {
3059 Builder.SetInsertPoint(CurBlock, CurBlock->begin());
3060 EmitAArch64CpuInit();
3061 AArch64CpuInitialized = true;
3062 Builder.SetInsertPoint(CurBlock);
3063 }
3064
3065 llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);
3066 CGBuilderTy RetBuilder(*this, RetBlock);
3068 SupportsIFunc);
3071 }
3072
3073
3074 Builder.SetInsertPoint(CurBlock);
3075 llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
3076 TrapCall->setDoesNotReturn();
3077 TrapCall->setDoesNotThrow();
3078 Builder.CreateUnreachable();
3079 Builder.ClearInsertionPoint();
3080}
3081
3084
3086
3087
3088 llvm::BasicBlock *CurBlock = createBasicBlock("resolver_entry", Resolver);
3089 Builder.SetInsertPoint(CurBlock);
3090 EmitX86CpuInit();
3091
3092 for (const FMVResolverOption &RO : Options) {
3093 Builder.SetInsertPoint(CurBlock);
3094 llvm::Value *Condition = FormX86ResolverCondition(RO);
3095
3096
3098 assert(&RO == Options.end() - 1 &&
3099 "Default or Generic case must be last");
3101 SupportsIFunc);
3102 return;
3103 }
3104
3105 llvm::BasicBlock *RetBlock = createBasicBlock("resolver_return", Resolver);
3106 CGBuilderTy RetBuilder(*this, RetBlock);
3108 SupportsIFunc);
3111 }
3112
3113
3114 Builder.SetInsertPoint(CurBlock);
3115 llvm::CallInst *TrapCall = EmitTrapCall(llvm::Intrinsic::trap);
3116 TrapCall->setDoesNotReturn();
3117 TrapCall->setDoesNotThrow();
3118 Builder.CreateUnreachable();
3119 Builder.ClearInsertionPoint();
3120}
3121
3122
3123
3124
3125
3126
3127
3130 SourceLocation SecondaryLoc, llvm::Value *Alignment,
3131 llvm::Value *OffsetValue, llvm::Value *TheCheck,
3132 llvm::Instruction *Assumption) {
3133 assert(isa_and_nonnullllvm::CallInst(Assumption) &&
3134 castllvm::CallInst(Assumption)->getCalledOperand() ==
3135 llvm::Intrinsic::getOrInsertDeclaration(
3136 Builder.GetInsertBlock()->getParent()->getParent(),
3137 llvm::Intrinsic::assume) &&
3138 "Assumption should be a call to llvm.assume().");
3139 assert(&(Builder.GetInsertBlock()->back()) == Assumption &&
3140 "Assumption should be the last instruction of the basic block, "
3141 "since the basic block is still being generated.");
3142
3143 if (.has(SanitizerKind::Alignment))
3144 return;
3145
3146
3147
3149 return;
3150
3151
3152
3153 Assumption->removeFromParent();
3154
3155 {
3156 SanitizerScope SanScope(this);
3157
3158 if (!OffsetValue)
3159 OffsetValue = Builder.getInt1(false);
3160
3167 EmitCheck({std::make_pair(TheCheck, SanitizerKind::SO_Alignment)},
3168 SanitizerHandler::AlignmentAssumption, StaticData, DynamicData);
3169 }
3170
3171
3172
3173 Builder.Insert(Assumption);
3174
3175}
3176
3179 return DI->SourceLocToDebugLoc(Location);
3180
3181 return llvm::DebugLoc();
3182}
3183
3184llvm::Value *
3185CodeGenFunction::emitCondLikelihoodViaExpectIntrinsic(llvm::Value *Cond,
3187 switch (LH) {
3189 return Cond;
3192
3193
3195 return Cond;
3196 llvm::Type *CondTy = Cond->getType();
3197 assert(CondTy->isIntegerTy(1) && "expecting condition to be a boolean");
3198 llvm::Function *FnExpect =
3200 llvm::Value *ExpectedValueOfCond =
3201 llvm::ConstantInt::getBool(CondTy, LH == Stmt::LH_Likely);
3202 return Builder.CreateCall(FnExpect, {Cond, ExpectedValueOfCond},
3203 Cond->getName() + ".expval");
3204 }
3205 llvm_unreachable("Unknown Likelihood");
3206}
3207
3209 unsigned NumElementsDst,
3210 const llvm::Twine &Name) {
3211 auto *SrcTy = castllvm::FixedVectorType(SrcVec->getType());
3212 unsigned NumElementsSrc = SrcTy->getNumElements();
3213 if (NumElementsSrc == NumElementsDst)
3214 return SrcVec;
3215
3216 std::vector ShuffleMask(NumElementsDst, -1);
3217 for (unsigned MaskIdx = 0;
3218 MaskIdx < std::min<>(NumElementsDst, NumElementsSrc); ++MaskIdx)
3219 ShuffleMask[MaskIdx] = MaskIdx;
3220
3221 return Builder.CreateShuffleVector(SrcVec, ShuffleMask, Name);
3222}
3223
3227 if (!PointerAuth.isSigned())
3228 return;
3229
3230 auto *Key = Builder.getInt32(PointerAuth.getKey());
3231
3232 llvm::Value *Discriminator = PointerAuth.getDiscriminator();
3233 if (!Discriminator)
3235
3236 llvm::Value *Args[] = {Key, Discriminator};
3237 Bundles.emplace_back("ptrauth", Args);
3238}
3239
3243 unsigned IntrinsicID) {
3244 if (!PointerAuth)
3246
3247 auto Key = CGF.Builder.getInt32(PointerAuth.getKey());
3248
3249 llvm::Value *Discriminator = PointerAuth.getDiscriminator();
3250 if (!Discriminator) {
3252 }
3253
3254
3255 auto OrigType = Pointer->getType();
3257
3258
3261
3262
3265}
3266
3267llvm::Value *
3273 llvm::Intrinsic::ptrauth_sign);
3274}
3275
3279 auto StripIntrinsic = CGF.CGM.getIntrinsic(llvm::Intrinsic::ptrauth_strip);
3280
3281 auto Key = CGF.Builder.getInt32(PointerAuth.getKey());
3282
3283 auto OrigType = Pointer->getType();
3286 return CGF.Builder.CreateIntToPtr(Pointer, OrigType);
3287}
3288
3289llvm::Value *
3294 }
3297 }
3298
3300 llvm::Intrinsic::ptrauth_auth);
3301}
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....
llvm::MachO::Target Target
Defines the Objective-C statement AST node classes.
Enumerates target-specific builtins in their own namespaces within namespace clang.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD) const
Parses the target attributes passed in, and returns only the ones that are valid feature names.
Builtin::Context & BuiltinInfo
QualType getFunctionTypeWithExceptionSpec(QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) const
Get a function type and produce the equivalent function type with the specified exception specificati...
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
bool hasAnyFunctionEffects() const
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
const VariableArrayType * getAsVariableArrayType(QualType T) const
const TargetInfo & getTargetInfo() const
void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
Attr - This represents one attribute.
A builtin binary operation expression such as "x + y" or "x <= y".
static bool isLogicalOp(Opcode Opc)
const char * getRequiredFeatures(unsigned ID) const
Represents a C++ constructor within a class.
Represents a static or instance method of a struct/union/class.
bool isImplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An implicit object member function is a non-static member function without an exp...
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getThisType() const
Return the type of the this pointer.
Represents a C++ struct/union/class.
bool isLambda() const
Determine whether this class describes a lambda function object.
void getCaptureFields(llvm::DenseMap< const ValueDecl *, FieldDecl * > &Captures, FieldDecl *&ThisCapture) const
For a closure type, retrieve the mapping from captured variables and this to the non-static data memb...
bool isCapturelessLambda() const
A C++ throw-expression (C++ [except.throw]).
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
CharUnits alignmentOfArrayElement(CharUnits elementSize) const
Given that this is the alignment of the first element of an array, return the minimum alignment of an...
bool isOne() const
isOne - Test whether the quantity equals one.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string SampleProfileFile
Name of the profile file to use with -fprofile-sample-use.
bool hasProfileClangInstr() const
Check if Clang profile instrumenation is on.
XRayInstrSet XRayInstrumentationBundle
Set of XRay instrumentation kinds to emit.
bool hasSanitizeCoverage() const
PointerAuthOptions PointerAuth
Configuration for pointer-signing.
bool hasReducedDebugInfo() const
Check if type and variable info should be emitted.
bool hasSanitizeBinaryMetadata() const
unsigned getInAllocaFieldIndex() const
bool getIndirectByVal() const
@ InAlloca
InAlloca - Pass the argument directly using the LLVM inalloca attribute.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
bool isSRetAfterThis() const
CharUnits getIndirectAlign() const
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
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 debug location to the specified location or preferred location of ...
static ApplyDebugLocation CreateDefaultArtificial(CodeGenFunction &CGF, SourceLocation TemporaryLocation)
Apply TemporaryLocation if it is valid.
This is an IRBuilder insertion helper that forwards to CodeGenFunction::InsertHelper,...
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const override
This forwards to CodeGenFunction::InsertHelper.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
llvm::LoadInst * CreateAlignedLoad(llvm::Type *Ty, llvm::Value *Addr, CharUnits Align, const llvm::Twine &Name="")
llvm::ConstantInt * getSize(CharUnits N)
Address CreateInBoundsGEP(Address Addr, ArrayRef< llvm::Value * > IdxList, llvm::Type *ElementType, CharUnits Align, const Twine &Name="")
virtual void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args)=0
Emits a kernel launch stub.
Implements C++ ABI-specific code generation functions.
virtual bool hasMostDerivedReturn(GlobalDecl GD) const
virtual bool HasThisReturn(GlobalDecl GD) const
Returns true if the given constructor or destructor is one of the kinds that the ABI says returns 'th...
virtual void EmitInstanceFunctionProlog(CodeGenFunction &CGF)=0
Emit the ABI-specific prolog for the function.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
void buildThisParam(CodeGenFunction &CGF, FunctionArgList &Params)
Build a parameter variable suitable for 'this'.
virtual void addImplicitStructorParams(CodeGenFunction &CGF, QualType &ResTy, FunctionArgList &Params)=0
Insert any ABI-specific implicit parameters into the parameter list for a function.
virtual RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const =0
Returns how an argument of the given record type should be passed.
MangleContext & getMangleContext()
Gets the mangle context.
All available information about a concrete callee.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
CGFunctionInfo - Class to encapsulate the information about a function definition.
ABIArgInfo & getReturnInfo()
bool isReturnsRetained() const
In ARC, whether this function retains its return value.
CanQualType getReturnType() const
bool isDelegateCall() const
unsigned getMaxVectorWidth() const
Return the maximum vector width in the arguments.
llvm::StructType * getArgStruct() const
Get the struct type used to represent all the arguments in memory.
void setHLSLFunctionAttributes(const FunctionDecl *FD, llvm::Function *Fn)
void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn)
virtual void functionFinished(CodeGenFunction &CGF)
Cleans up references to the objects in finished function.
llvm::OpenMPIRBuilder & getOMPBuilder()
virtual void emitFunctionProlog(CodeGenFunction &CGF, const Decl *D)
Emits OpenMP-specific function prolog.
llvm::Value * getDiscriminator() const
virtual ~CGCapturedStmtInfo()
CGFPOptionsRAII(CodeGenFunction &CGF, FPOptions FPFeatures)
SanitizerScope(CodeGenFunction *CGF)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitPointerAuthAuth(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
void EmitDestructorBody(FunctionArgList &Args)
void EmitBranchToCounterBlock(const Expr *Cond, BinaryOperator::Opcode LOp, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount=0, Stmt::Likelihood LH=Stmt::LH_None, const Expr *CntrIdx=nullptr)
EmitBranchToCounterBlock - Emit a conditional branch to a new block that increments a profile counter...
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
void EmitNullInitialization(Address DestPtr, QualType Ty)
EmitNullInitialization - Generate code to set a value of the given type to null, If the type contains...
void EmitPointerAuthOperandBundle(const CGPointerAuthInfo &Info, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
GlobalDecl CurGD
CurGD - The GlobalDecl for the current function being compiled.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
static bool ContainsLabel(const Stmt *S, bool IgnoreCaseStmts=false)
ContainsLabel - Return true if the statement contains a label in it.
void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock, llvm::BasicBlock *FalseBlock, uint64_t TrueCount, Stmt::Likelihood LH=Stmt::LH_None, const Expr *ConditionalOp=nullptr)
EmitBranchOnBoolExpr - Emit a branch on a boolean condition (e.g.
llvm::CallInst * EmitTrapCall(llvm::Intrinsic::ID IntrID)
Emit a call to trap or debugtrap and attach function attribute "trap-func-name" if specified.
JumpDest getJumpDestInCurrentScope(llvm::BasicBlock *Target)
The given basic block lies in the current EH scope, but may be a target of a potentially scope-crossi...
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK)
SanitizerSet SanOpts
Sanitizers enabled for this function.
void EmitAArch64MultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
void unprotectFromPeepholes(PeepholeProtection protection)
void EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD)
bool ShouldInstrumentFunction()
ShouldInstrumentFunction - Return true if the current function should be instrumented with __cyg_prof...
Address EmitCompoundStmtWithoutScope(const CompoundStmt &S, bool GetLast=false, AggValueSlot AVS=AggValueSlot::ignored())
static bool hasScalarEvaluationKind(QualType T)
void EmitMultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
FieldDecl * LambdaThisCaptureField
LValue MakeNaturalAlignPointeeRawAddrLValue(llvm::Value *V, QualType T)
Same as MakeNaturalAlignPointeeAddrLValue except that the pointer is known to be unsigned.
void EmitKCFIOperandBundle(const CGCallee &Callee, SmallVectorImpl< llvm::OperandBundleDef > &Bundles)
void emitAlignmentAssumptionCheck(llvm::Value *Ptr, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue, llvm::Value *TheCheck, llvm::Instruction *Assumption)
llvm::BlockAddress * GetAddrOfLabel(const LabelDecl *L)
RawAddress CreateDefaultAlignTempAlloca(llvm::Type *Ty, const Twine &Name="tmp")
CreateDefaultAlignedTempAlloca - This creates an alloca with the default ABI alignment of the given L...
llvm::Value * emitArrayLength(const ArrayType *arrayType, QualType &baseType, Address &addr)
emitArrayLength - Compute the length of an array, even if it's a VLA, and drill down to the base elem...
VlaSizePair getVLASize(const VariableArrayType *vla)
Returns an LLVM value that corresponds to the size, in non-variably-sized elements,...
void EmitEndEHSpec(const Decl *D)
EmitEndEHSpec - Emit the end of the exception spec.
llvm::Value * EmitRISCVCpuSupports(const CallExpr *E)
bool CurFuncIsThunk
In C++, whether we are code generating a thunk.
SmallVector< llvm::ConvergenceControlInst *, 4 > ConvergenceTokenStack
Stack to track the controlled convergence tokens.
LValue EmitLValue(const Expr *E, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitLValue - Emit code to compute a designator that specifies the location of the expression.
llvm::SmallVector< DeferredDeactivateCleanup > DeferredDeactivationCleanupStack
void EmitVariablyModifiedType(QualType Ty)
EmitVLASize - Capture all the sizes for the VLA expressions in the given variably-modified type and s...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc)
EmitFunctionEpilog - Emit the target specific LLVM code to return the given temporary.
llvm::Constant * EmitCheckTypeDescriptor(QualType T)
Emit a description of a type in a format suitable for passing to a runtime sanitizer handler.
llvm::BasicBlock * EHResumeBlock
EHResumeBlock - Unified block containing a call to llvm.eh.resume.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
static bool isInstrumentedCondition(const Expr *C)
isInstrumentedCondition - Determine whether the given condition is an instrumentable condition (i....
void EmitFunctionBody(const Stmt *Body)
void EmitRISCVMultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
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.
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
@ TCK_ConstructorCall
Checking the 'this' pointer for a constructor call.
@ TCK_MemberCall
Checking the 'this' pointer for a call to a non-static member function.
void setCurrentProfileCount(uint64_t Count)
Set the profiler's current count.
void EmitIgnoredExpr(const Expr *E)
EmitIgnoredExpr - Emit an expression in a context which ignores the result.
void PopCleanupBlocks(EHScopeStack::stable_iterator OldCleanupStackSize, std::initializer_list< llvm::Value ** > ValuesToReload={})
Takes the old cleanup stack size and emits the cleanup blocks that have been added.
llvm::Type * ConvertTypeForMem(QualType T)
const Decl * CurCodeDecl
CurCodeDecl - This is the inner-most code context, which includes blocks.
llvm::AssertingVH< llvm::Instruction > AllocaInsertPt
AllocaInsertPoint - This is an instruction in the entry block before which we prefer to insert alloca...
bool AlwaysEmitXRayCustomEvents() const
AlwaysEmitXRayCustomEvents - Return true if we must unconditionally emit XRay custom event handling c...
JumpDest ReturnBlock
ReturnBlock - Unified return block.
void EmitVarAnnotations(const VarDecl *D, llvm::Value *V)
Emit local annotations for the local variable V, declared by D.
llvm::Value * EmitPointerAuthSign(const CGPointerAuthInfo &Info, llvm::Value *Pointer)
static const Expr * stripCond(const Expr *C)
Ignore parentheses and logical-NOT to track conditions consistently.
PeepholeProtection protectFromPeepholes(RValue rvalue)
protectFromPeepholes - Protect a value that we're intending to store to the side, but which will prob...
const TargetInfo & getTarget() const
llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Location)
Converts Location to a DebugLoc, if debug information is enabled.
void EmitFunctionProlog(const CGFunctionInfo &FI, llvm::Function *Fn, const FunctionArgList &Args)
EmitFunctionProlog - Emit the target specific LLVM code to load the arguments for the given function.
Address EmitPointerWithAlignment(const Expr *Addr, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
EmitPointerWithAlignment - Given an expression with a pointer type, emit the value and compute our be...
void EmitX86MultiVersionResolver(llvm::Function *Resolver, ArrayRef< FMVResolverOption > Options)
llvm::Value * EmitRISCVCpuInit()
void EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S)
void EmitCheck(ArrayRef< std::pair< llvm::Value *, SanitizerKind::SanitizerOrdinal > > Checked, SanitizerHandler Check, ArrayRef< llvm::Constant * > StaticArgs, ArrayRef< llvm::Value * > DynamicArgs)
Create a basic block that will either trap or call a handler function in the UBSan runtime with the p...
bool ShouldSkipSanitizerInstrumentation()
ShouldSkipSanitizerInstrumentation - Return true if the current function should not be instrumented w...
uint64_t getCurrentProfileCount()
Get the profiler's current count.
SmallVector< const BinaryOperator *, 16 > MCDCLogOpStack
Stack to track the Logical Operator recursion nest for MC/DC.
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
bool HaveInsertPoint() const
HaveInsertPoint - True if an insertion point is defined.
llvm::Constant * EmitCheckSourceLocation(SourceLocation Loc)
Emit a description of a source location in a format suitable for passing to a runtime sanitizer handl...
void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn)
Annotate the function with an attribute that disables TSan checking at runtime.
void ErrorUnsupported(const Stmt *S, const char *Type)
ErrorUnsupported - Print out an error that codegen doesn't support the specified stmt yet.
CGDebugInfo * getDebugInfo()
Address EmitVAListRef(const Expr *E)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
void maybeCreateMCDCCondBitmap()
Allocate a temp value on the stack that MCDC can use to track condition results.
void emitAlignmentAssumption(llvm::Value *PtrValue, QualType Ty, SourceLocation Loc, SourceLocation AssumptionLoc, llvm::Value *Alignment, llvm::Value *OffsetValue=nullptr)
llvm::Value * emitBoolVecConversion(llvm::Value *SrcVec, unsigned NumElementsDst, const llvm::Twine &Name="")
LValue MakeNaturalAlignRawAddrLValue(llvm::Value *V, QualType T)
bool ShouldXRayInstrumentFunction() const
ShouldXRayInstrument - Return true if the current function should be instrumented with XRay nop sleds...
void EmitStartEHSpec(const Decl *D)
EmitStartEHSpec - Emit the start of the exception spec.
llvm::Value * EmitCheckValue(llvm::Value *V)
Convert a value into a format suitable for passing to a runtime sanitizer handler.
VlaSizePair getVLAElements1D(const VariableArrayType *vla)
Return the number of elements for a single dimension for the given array type.
bool AlwaysEmitXRayTypedEvents() const
AlwaysEmitXRayTypedEvents - Return true if clang must unconditionally emit XRay typed event handling ...
void EmitConstructorBody(FunctionArgList &Args)
void SetFastMathFlags(FPOptions FPFeatures)
Set the codegen fast-math flags.
ASTContext & getContext() const
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void maybeUpdateMCDCCondBitmap(const Expr *E, llvm::Value *Val)
Update the MCDC temp value with the condition's evaluated result.
void checkTargetFeatures(const CallExpr *E, const FunctionDecl *TargetDecl)
void EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD)
llvm::SmallVector< char, 256 > LifetimeExtendedCleanupStack
void EmitDeclRefExprDbgValue(const DeclRefExpr *E, const APValue &Init)
void EmitCXXThrowExpr(const CXXThrowExpr *E, bool KeepInsertionPoint=true)
bool ConstantFoldsToSimpleInteger(const Expr *Cond, bool &Result, bool AllowLabels=false)
ConstantFoldsToSimpleInteger - If the specified expression does not fold to a constant,...
Address ReturnValuePointer
ReturnValuePointer - The temporary alloca to hold a pointer to sret.
llvm::ConstantInt * getUBSanFunctionTypeHash(QualType T) const
Return a type hash constant for a function instrumented by -fsanitize=function.
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
JumpDest getJumpDestForLabel(const LabelDecl *S)
getBasicBlockForLabel - Return the LLVM basicblock that the specified label maps to.
llvm::DenseMap< const ValueDecl *, FieldDecl * > LambdaCaptureFields
bool AutoreleaseResult
In ARC, whether we should autorelease the return value.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
llvm::Type * ConvertType(QualType T)
CodeGenTypes & getTypes() const
bool IsSanitizerScope
True if CodeGen currently emits code implementing sanitizer checks.
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.
QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args)
RawAddress NormalCleanupDest
i32s containing the indexes of the cleanup destinations.
llvm::Value * EvaluateExprAsBool(const Expr *E)
EvaluateExprAsBool - Perform the usual unary conversions on the specified expression and compare the ...
Address EmitMSVAListRef(const Expr *E)
Emit a "reference" to a __builtin_ms_va_list; this is always the value of the expression,...
VarBypassDetector Bypasses
EHScopeStack::stable_iterator PrologueCleanupDepth
PrologueCleanupDepth - The cleanup depth enclosing all the cleanups associated with the parameters.
static bool mightAddDeclToScope(const Stmt *S)
Determine if the given statement might introduce a declaration into the current scope,...
uint64_t getProfileCount(const Stmt *S)
Get the profiler's count for the given statement.
RawAddress CreateIRTemp(QualType T, const Twine &Name="tmp")
CreateIRTemp - Create a temporary IR object of the given type, with appropriate alignment.
void emitImplicitAssignmentOperatorBody(FunctionArgList &Args)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
const CGFunctionInfo * CurFnInfo
LValue MakeNaturalAlignAddrLValue(llvm::Value *V, QualType T, KnownNonNull_t IsKnownNonNull=NotKnownNonNull)
void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, llvm::BasicBlock::iterator InsertPt) const
CGBuilder insert helper.
Address EmitFieldAnnotations(const FieldDecl *D, Address V)
Emit field annotations for the given field & value.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
void EnsureInsertPoint()
EnsureInsertPoint - Ensure that an insertion point is defined so that emitted IR has a place to go.
LValue MakeNaturalAlignPointeeAddrLValue(llvm::Value *V, QualType T)
Given a value of type T* that may not be to a complete object, construct an l-value with the natural ...
llvm::LLVMContext & getLLVMContext()
bool SawAsmBlock
Whether we processed a Microsoft-style asm block during CodeGen.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
bool checkIfFunctionMustProgress()
Returns true if a function must make progress, which means the mustprogress attribute can be added.
void incrementProfileCounter(const Stmt *S, llvm::Value *StepV=nullptr)
Increment the profiler's counter for the given statement by StepV.
llvm::Value * EmitAnnotationCall(llvm::Function *AnnotationFn, llvm::Value *AnnotatedVal, StringRef AnnotationStr, SourceLocation Location, const AnnotateAttr *Attr)
Emit an annotation call (intrinsic).
llvm::BasicBlock * GetIndirectGotoBlock()
llvm::Type * convertTypeForLoadStore(QualType ASTTy, llvm::Type *LLVMTy=nullptr)
llvm::DebugLoc EmitReturnBlock()
Emit the unified return block, trying to avoid its emission when possible.
void GenerateCode(GlobalDecl GD, llvm::Function *Fn, const CGFunctionInfo &FnInfo)
LValue EmitLValueForLambdaField(const FieldDecl *Field)
static bool containsBreak(const Stmt *S)
containsBreak - Return true if the statement contains a break out of it.
This class organizes the cross-function state that is used while generating LLVM code.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::Constant * EmitAnnotationArgs(const AnnotateAttr *Attr)
Emit additional args of the annotation.
llvm::Module & getModule() const
DiagnosticsEngine & getDiags() const
void ErrorUnsupported(const Stmt *S, const char *Type)
Print out an error that codegen doesn't support the specified stmt yet.
const LangOptions & getLangOpts() const
CGCUDARuntime & getCUDARuntime()
Return a reference to the configured CUDA runtime.
llvm::Constant * EmitAnnotationLineNo(SourceLocation L)
Emit the annotation line number.
CharUnits getNaturalTypeAlignment(QualType T, LValueBaseInfo *BaseInfo=nullptr, TBAAAccessInfo *TBAAInfo=nullptr, bool forPointeeType=false)
CodeGenTypes & getTypes()
const llvm::DataLayout & getDataLayout() const
bool shouldEmitConvergenceTokens() const
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, StringRef Category=StringRef()) const
Imbue XRay attributes to a function, applying the always/never attribute lists in the process.
ProfileList::ExclusionType isFunctionBlockedFromProfileInstr(llvm::Function *Fn, SourceLocation Loc) const
ASTContext & getContext() const
llvm::SanitizerStatReport & getSanStats()
llvm::Constant * EmitAnnotationString(StringRef Str)
Emit an annotation string.
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
void GenKernelArgMetadata(llvm::Function *FN, const FunctionDecl *FD=nullptr, CodeGenFunction *CGF=nullptr)
OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument information in the program executab...
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
llvm::Constant * EmitNullConstant(QualType T)
Return the result of value-initializing the given type, i.e.
llvm::ConstantInt * CreateKCFITypeId(QualType T)
Generate a KCFI type identifier for T.
bool MayDropFunctionReturn(const ASTContext &Context, QualType ReturnType) const
Whether this function's return type has no side effects, and thus may be trivially discarded if it is...
llvm::Constant * EmitAnnotationUnit(SourceLocation Loc)
Emit the annotation's translation unit.
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
void assignRegionCounters(GlobalDecl GD, llvm::Function *Fn)
Assign counters to regions and configure them for PGO of a given function.
void verifyCounterMap() const
void markStmtMaybeUsed(const Stmt *S)
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...
llvm::Type * convertTypeForLoadStore(QualType T, llvm::Type *LLVMTy=nullptr)
Given that T is a scalar type, return the IR type that should be used for load and store operations.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
bool isZeroInitializable(QualType T)
IsZeroInitializable - Return whether a type can be zero-initialized (in the C++ sense) with an LLVM z...
stable_iterator stable_begin() const
Create a stable reference to the top of the EH stack.
bool containsOnlyLifetimeMarkers(stable_iterator Old) const
bool empty() const
Determines whether the exception-scopes stack is empty.
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
llvm::Value * getPointer(CodeGenFunction &CGF) const
Address getAddress() const
void InsertHelper(llvm::Instruction *I) const
Function called by the CodeGenFunction when an instruction is created.
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
llvm::Value * getPointer() const
virtual void checkFunctionABI(CodeGenModule &CGM, const FunctionDecl *Decl) const
Any further codegen related checks that need to be done on a function signature in a target specific ...
virtual llvm::Constant * getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const
Return a constant used by UBSan as a signature to identify functions possessing type information,...
void Init(const Stmt *Body)
Clear the object and pre-process for the given statement, usually function body statement.
CompoundStmt - This represents a group of statements like { stmt stmt }.
ConditionalOperator - The ?: ternary operator.
A reference to a declared variable, function, enum, etc.
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
Decl * getNonClosureContext()
Find the innermost non-closure ancestor of this declaration, walking up through blocks,...
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
SourceLocation getLocation() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
FPOptions getFPFeaturesInEffect(const LangOptions &LO) const
Returns the set of floating point options that apply to this expression.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
ExtVectorType - Extended vector type.
LangOptions::FPExceptionModeKind getExceptionMode() const
bool allowFPContractAcrossStatement() const
RoundingMode getRoundingMode() const
Represents a member of a struct/union/class.
Represents a function declaration or definition.
bool isMultiVersion() const
True if this function is considered a multiversioned function.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
bool UsesFPIntrin() const
Determine whether the function was declared in source context that requires constrained FP intrinsics...
bool usesSEHTry() const
Indicates the function uses __try.
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
FunctionDecl * getTemplateInstantiationPattern(bool ForDefinition=true) const
Retrieve the function declaration from which this function could be instantiated, if it is an instant...
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.
Represents a prototype with parameter type info, e.g.
GlobalDecl - represents a global declaration.
CXXCtorType getCtorType() const
const Decl * getDecl() const
One of these records is kept for each identifier that is lexed.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
Represents the declaration of a label.
FPExceptionModeKind
Possible floating point exception behavior.
@ FPE_Strict
Strictly preserve the floating-point exception semantics.
@ FPE_MayTrap
Transformations do not cause new exceptions but may hide some.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
SanitizerSet Sanitize
Set of enabled sanitizers.
RoundingMode getDefaultRoundingMode() const
virtual void mangleCanonicalTypeName(QualType T, raw_ostream &, bool NormalizeIntegers=false)=0
Generates a unique string for an externally visible type for use with TBAA or type uniquing.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Represents a parameter to a function.
ParsedAttr - Represents a syntactic attribute.
PointerType - C99 6.7.5.1 - Pointer Declarators.
@ Forbid
Profiling is forbidden using the noprofile attribute.
@ Skip
Profiling is skipped using the skipprofile attribute.
@ Allow
Profiling is allowed.
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
decl_type * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Likelihood
The likelihood of a branch being taken.
@ LH_Unlikely
Branch has the [[unlikely]] attribute.
@ LH_None
No attribute set or branches of the IfStmt have the same attribute.
@ LH_Likely
Branch has the [[likely]] attribute.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool supportsIFunc() const
Identify whether this target supports IFuncs.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
virtual std::optional< std::pair< unsigned, unsigned > > getVScaleRange(const LangOptions &LangOpts) const
Returns target-specific min and max values VScale_Range.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isPointerType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
TypeClass getTypeClass() const
const T * getAs() const
Member-template getAs'.
bool isRecordType() const
bool isObjCRetainableType() const
std::optional< NullabilityKind > getNullability() const
Determine the nullability of the given type.
bool isFunctionNoProtoType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a variable declaration or definition.
Represents a C array with a specified size that is not an integer-constant-expression.
Expr * getSizeExpr() const
QualType getElementType() const
Defines the clang::TargetInfo interface.
bool evaluateRequiredTargetFeatures(llvm::StringRef RequiredFatures, const llvm::StringMap< bool > &TargetFetureMap)
Returns true if the required target features of a builtin function are enabled.
TypeEvaluationKind
The kind of evaluation to perform on values of a particular type.
constexpr XRayInstrMask Typed
constexpr XRayInstrMask FunctionExit
constexpr XRayInstrMask FunctionEntry
constexpr XRayInstrMask Custom
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const AstTypeMatcher< ArrayType > arrayType
Matches all kinds of arrays.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ NonNull
Values of this type can never be null.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
const FunctionProtoType * T
llvm::fp::ExceptionBehavior ToConstrainedExceptMD(LangOptions::FPExceptionModeKind Kind)
@ Other
Other implicit parameter.
@ EST_None
no exception specification
@ Implicit
An implicit conversion.
Diagnostic wrappers for TextAPI types for error reporting.
cl::opt< bool > EnableSingleByteCoverage
llvm::BasicBlock * getBlock() const
This structure provides a set of types that are commonly used during IR emission.
llvm::PointerType * ConstGlobalsPtrTy
void* in the address space for constant globals
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * Int32Ty
llvm::IntegerType * IntPtrTy
llvm::PointerType * Int8PtrTy
CharUnits getPointerAlign() const
EvalResult is a struct with detailed info about an evaluated expression.
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
bool ReturnAddresses
Should return addresses be authenticated?
bool AArch64JumpTableHardening
Use hardened lowering for jump-table dispatch?
PointerAuthSchema FunctionPointers
The ABI for C function pointers.
bool AuthTraps
Do authentication failures cause a trap?
bool IndirectGotos
Do indirect goto label addresses need to be authenticated?
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
SanitizerMask Mask
Bitmask of enabled sanitizers.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
bool has(XRayInstrMask K) const