21#include "llvm/ADT/StringExtras.h"
22#include "llvm/IR/Intrinsics.h"
23#include "llvm/IR/MDBuilder.h"
24#include "llvm/Support/Path.h"
27using namespace CodeGen;
34 "VarDecl must have global or local (in the case of OpenCL) storage!");
36 "Should not call EmitDeclInit on a reference!");
66 llvm_unreachable(
"bad evaluation kind");
94 assert(!D.
getTLSKind() &&
"should have rejected this");
98 llvm::FunctionCallee
Func;
99 llvm::Constant *Argument;
109 bool CanRegisterDestructor =
117 if (Record && (CanRegisterDestructor || UsingExternalHelper)) {
118 assert(!Record->hasTrivialDestructor());
125 auto DestTy = llvm::PointerType::get(
133 Argument = llvm::ConstantPointerNull::get(DestTy);
143 Argument = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
152 llvm::Constant *Addr) {
157void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr,
CharUnits Size) {
163 llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
166 llvm::Function *InvariantStart =
CGM.
getIntrinsic(InvStartID, ObjectPtr);
170 llvm::Value *Args[2] = {llvm::ConstantInt::getSigned(
Int64Ty, Width), Addr};
171 Builder.CreateCall(InvariantStart, Args);
175 llvm::GlobalVariable *GV,
197 unsigned ActualAddrSpace = GV->getAddressSpace();
198 llvm::Constant *DeclPtr = GV;
199 if (ActualAddrSpace != ExpectedAddrSpace) {
200 llvm::PointerType *PTy =
202 DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
206 DeclPtr, GV->getValueType(),
getContext().getDeclAlign(&D));
210 D.
hasAttr<OMPThreadPrivateDeclAttr>()) {
212 &D, DeclAddr, D.
getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
226 assert(PerformInit &&
"cannot have constant initializer which needs "
227 "destruction for reference");
235 llvm::FunctionCallee dtor,
236 llvm::Constant *addr) {
238 llvm::FunctionType *ty = llvm::FunctionType::get(
CGM.
VoidTy,
false);
241 llvm::raw_svector_ostream Out(FnName);
257 llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
260 if (
auto *dtorFn = dyn_cast<llvm::Function>(
261 dtor.getCallee()->stripPointerCastsAndAliases()))
262 call->setCallingConv(dtorFn->getCallingConv());
264 CGF.FinishFunction();
272 const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr,
273 llvm::FunctionCallee &
AtExit) {
276 llvm::raw_svector_ostream Out(FnName);
285 llvm::FunctionType *StubTy =
286 llvm::FunctionType::get(
CGM.
IntTy, {CGM.IntTy},
true);
296 Args.push_back(&IPD);
305 llvm::CallInst *call = CGF.Builder.CreateCall(Dtor, Addr);
308 if (
auto *DtorFn = dyn_cast<llvm::Function>(
309 Dtor.getCallee()->stripPointerCastsAndAliases()))
310 call->setCallingConv(DtorFn->getCallingConv());
313 CGF.Builder.CreateStore(llvm::Constant::getNullValue(
CGM.
IntTy),
316 CGF.FinishFunction();
323 llvm::FunctionCallee dtor,
324 llvm::Constant *addr) {
332 llvm::FunctionCallee Dtor,
333 llvm::Constant *Addr) {
341 assert(dtorStub->getType() ==
342 llvm::PointerType::get(
343 llvm::FunctionType::get(
CGM.
VoidTy,
false),
344 dtorStub->getType()->getPointerAddressSpace()) &&
345 "Argument to atexit has a wrong type.");
347 llvm::FunctionType *atexitTy =
348 llvm::FunctionType::get(
IntTy, dtorStub->getType(),
false);
350 llvm::FunctionCallee atexit =
353 if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee()))
354 atexitFn->setDoesNotThrow();
368 assert(dtorStub->getType() ==
369 llvm::PointerType::get(
370 llvm::FunctionType::get(
CGM.
VoidTy,
false),
371 dtorStub->getType()->getPointerAddressSpace()) &&
372 "Argument to unatexit has a wrong type.");
374 llvm::FunctionType *unatexitTy =
375 llvm::FunctionType::get(
IntTy, {dtorStub->getType()},
false);
377 llvm::FunctionCallee unatexit =
380 cast<llvm::Function>(unatexit.getCallee())->setDoesNotThrow();
386 llvm::GlobalVariable *DeclPtr,
393 "this initialization requires a guard variable, which "
394 "the kernel does not support");
400 llvm::BasicBlock *InitBlock,
401 llvm::BasicBlock *NoInitBlock,
408 static const uint64_t InitsPerTLSVar = 1024;
409 static const uint64_t InitsPerLocalVar = 1024 * 1024;
411 llvm::MDNode *Weights;
423 NumInits = InitsPerTLSVar;
425 NumInits = InitsPerLocalVar;
430 Weights = MDHelper.createBranchWeights(1, NumInits - 1);
433 Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);
437 llvm::FunctionType *FTy,
const Twine &Name,
const CGFunctionInfo &FI,
439 llvm::Function *Fn = llvm::Function::Create(FTy,
Linkage, Name, &
getModule());
443 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
444 Fn->setSection(Section);
447 if (
Linkage == llvm::GlobalVariable::InternalLinkage)
453 Fn->setDoesNotThrow();
455 if (
getLangOpts().Sanitize.has(SanitizerKind::Address) &&
457 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
459 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&
461 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
463 if (
getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&
465 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
467 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) &&
469 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
471 if (
getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&
473 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
475 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
477 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
479 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
481 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
483 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) &&
485 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
487 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
489 Fn->addFnAttr(llvm::Attribute::SafeStack);
491 if (
getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) &&
493 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
501void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *D,
502 llvm::GlobalVariable *GV,
503 llvm::Function *InitFunc,
505 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
506 TheModule, InitFunc->getType(),
true,
507 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
508 PtrArray->setSection(ISA->getSection());
512 if (llvm::Comdat *
C = GV->getComdat())
513 PtrArray->setComdat(
C);
517CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *D,
518 llvm::GlobalVariable *Addr,
527 (D->
hasAttr<CUDADeviceAttr>() || D->
hasAttr<CUDAConstantAttr>() ||
532 auto I = DelayedCXXInitPosition.find(D);
533 if (I != DelayedCXXInitPosition.end() && I->second == ~0
U)
536 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
539 llvm::raw_svector_ostream Out(FnName);
547 auto *ISA = D->
getAttr<InitSegAttr>();
551 llvm::GlobalVariable *COMDATKey =
558 CXXThreadLocalInits.push_back(Fn);
559 CXXThreadLocalInitVars.push_back(D);
560 }
else if (PerformInit && ISA) {
564 if (ISA->getSection() ==
".CRT$XCC")
566 else if (ISA->getSection() ==
".CRT$XCL")
572 EmitPointerToInitFunc(D, Addr, Fn, ISA);
573 }
else if (
auto *IPA = D->
getAttr<InitPriorityAttr>()) {
575 PrioritizedCXXGlobalInits.size());
576 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
596 I = DelayedCXXInitPosition.find(D);
604 I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;
606 if (COMDATKey && (
getTriple().isOSBinFormatELF() ||
616 llvm::Comdat *
C = Addr->getComdat();
617 if (COMDATKey &&
C &&
623 I = DelayedCXXInitPosition.find(D);
624 if (I == DelayedCXXInitPosition.end()) {
625 CXXGlobalInits.push_back(Fn);
626 }
else if (I->second != ~0
U) {
627 assert(I->second < CXXGlobalInits.size() &&
628 CXXGlobalInits[I->second] ==
nullptr);
629 CXXGlobalInits[I->second] = Fn;
634 DelayedCXXInitPosition[D] = ~0
U;
637void CodeGenModule::EmitCXXThreadLocalInitFunc() {
639 *
this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
641 CXXThreadLocalInits.clear();
642 CXXThreadLocalInitVars.clear();
643 CXXThreadLocals.clear();
661void CodeGenModule::EmitCXXModuleInitFunc(
Module *Primary) {
663 "The function should only be called for C++20 named module interface"
666 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
667 CXXGlobalInits.pop_back();
675 for (
auto I : Primary->
Exports)
676 AllImports.insert(I.getPointer());
679 AllImports.insert(M);
683 assert((SubM->isGlobalModule() || SubM->isPrivateModule()) &&
684 "The sub modules of C++20 module unit should only be global module "
685 "fragments or private module framents.");
686 assert(SubM->Exports.empty() &&
687 "The global mdoule fragments and the private module fragments are "
688 "not allowed to export import modules.");
690 AllImports.insert(M);
694 for (
Module *M : AllImports) {
702 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
705 llvm::raw_svector_ostream Out(FnName);
706 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
707 .mangleModuleInitializer(M, Out);
710 "We should only have one use of the initializer call");
711 llvm::Function *Fn = llvm::Function::Create(
712 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
713 ModuleInits.push_back(Fn);
718 if (!PrioritizedCXXGlobalInits.empty()) {
720 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
721 PrioritizedCXXGlobalInits.end());
723 I = PrioritizedCXXGlobalInits.begin(),
724 E = PrioritizedCXXGlobalInits.end();
727 std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
729 for (; I < PrioE; ++I)
730 ModuleInits.push_back(I->second);
735 for (
auto *F : CXXGlobalInits)
736 ModuleInits.push_back(F);
738 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
748 llvm::raw_svector_ostream Out(InitFnName);
749 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
750 .mangleModuleInitializer(Primary, Out);
753 llvm::GlobalVariable::ExternalLinkage);
758 if (!ModuleInits.empty()) {
760 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
762 llvm::GlobalVariable::InternalLinkage,
763 llvm::ConstantInt::get(
Int8Ty, 0), InitFnName.str() +
"__in_chrg");
782 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
788 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
789 Fn->addFnAttr(
"device-init");
794 PrioritizedCXXGlobalInits.clear();
795 CXXGlobalInits.clear();
805 for (
size_t i = 0; i <
FileName.size(); ++i) {
816 assert(
Priority <= 65535 &&
"Priority should always be <= 65535.");
820 std::string PrioritySuffix = llvm::utostr(
Priority);
821 PrioritySuffix = std::string(6 - PrioritySuffix.size(),
'0') + PrioritySuffix;
823 return PrioritySuffix;
827CodeGenModule::EmitCXXGlobalInitFunc() {
828 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
829 CXXGlobalInits.pop_back();
833 if (CXX20ModuleInits)
834 for (
Module *M : ImportedModules) {
838 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
841 llvm::raw_svector_ostream Out(FnName);
842 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
843 .mangleModuleInitializer(M, Out);
846 "We should only have one use of the initializer call");
847 llvm::Function *Fn = llvm::Function::Create(
848 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
849 ModuleInits.push_back(Fn);
852 if (ModuleInits.empty() && CXXGlobalInits.empty() &&
853 PrioritizedCXXGlobalInits.empty())
856 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
860 if (!PrioritizedCXXGlobalInits.empty()) {
862 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
863 PrioritizedCXXGlobalInits.end());
868 I = PrioritizedCXXGlobalInits.begin(),
869 E = PrioritizedCXXGlobalInits.end(); I != E; ) {
871 PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
873 LocalCXXGlobalInits.clear();
875 unsigned int Priority = I->first.priority;
880 if (!ModuleInits.empty()) {
881 for (
auto *F : ModuleInits)
882 LocalCXXGlobalInits.push_back(F);
886 for (; I < PrioE; ++I)
887 LocalCXXGlobalInits.push_back(I->second);
892 PrioritizedCXXGlobalInits.clear();
895 if (
getCXXABI().useSinitAndSterm() && ModuleInits.empty() &&
896 CXXGlobalInits.empty())
899 for (
auto *F : CXXGlobalInits)
900 ModuleInits.push_back(F);
901 CXXGlobalInits.clear();
908 if (CXX20ModuleInits &&
getContext().getCurrentNamedModule() &&
909 !
getContext().getCurrentNamedModule()->isModuleImplementation()) {
911 llvm::raw_svector_ostream Out(InitFnName);
912 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
913 .mangleModuleInitializer(
getContext().getCurrentNamedModule(), Out);
916 llvm::GlobalVariable::ExternalLinkage);
936 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
942 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
943 Fn->addFnAttr(
"device-init");
949void CodeGenModule::EmitCXXGlobalCleanUpFunc() {
950 if (CXXGlobalDtorsOrStermFinalizers.empty() &&
951 PrioritizedCXXStermFinalizers.empty())
954 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
958 if (!PrioritizedCXXStermFinalizers.empty()) {
960 llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(),
961 PrioritizedCXXStermFinalizers.end());
966 I = PrioritizedCXXStermFinalizers.begin(),
967 E = PrioritizedCXXStermFinalizers.end();
970 std::upper_bound(I + 1, E, *I, StermFinalizerPriorityCmp());
972 LocalCXXStermFinalizers.clear();
974 unsigned int Priority = I->first.priority;
978 for (; I < PrioE; ++I) {
979 llvm::FunctionCallee DtorFn = I->second;
980 LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),
981 DtorFn.getCallee(),
nullptr);
985 Fn, LocalCXXStermFinalizers);
988 PrioritizedCXXStermFinalizers.clear();
991 if (CXXGlobalDtorsOrStermFinalizers.empty())
999 Fn, CXXGlobalDtorsOrStermFinalizers);
1001 CXXGlobalDtorsOrStermFinalizers.clear();
1007 llvm::GlobalVariable *Addr,
1010 if (D->
hasAttr<NoDebugAttr>())
1011 DebugInfo =
nullptr;
1028 if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage() ||
1053 llvm::BasicBlock *ExitBlock =
nullptr;
1058 llvm::Value *Uninit =
Builder.CreateIsNull(GuardVal,
1059 "guard.uninitialized");
1077 RunCleanupsScope
Scope(*
this);
1086 for (
unsigned i = 0, e = Decls.size(); i != e; ++i)
1090 Scope.ForceCleanup();
1103 ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
1105 DtorsOrStermFinalizers) {
1114 for (
unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) {
1115 llvm::FunctionType *CalleeTy;
1117 llvm::Constant *Arg;
1118 std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];
1120 llvm::CallInst *CI =
nullptr;
1121 if (Arg ==
nullptr) {
1124 "Arg could not be nullptr unless using sinit and sterm functions.");
1125 CI =
Builder.CreateCall(CalleeTy, Callee);
1127 CI =
Builder.CreateCall(CalleeTy, Callee, Arg);
1130 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
1131 CI->setCallingConv(F->getCallingConv());
1143 bool useEHCleanupForArray,
const VarDecl *VD) {
1147 args.push_back(&Dst);
1153 FTy,
"__cxx_global_array_dtor", FI, VD->
getLocation());
static std::string getPrioritySuffix(unsigned int Priority)
static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, ConstantAddress DeclPtr)
static SmallString< 128 > getTransformedFileName(llvm::Module &M)
static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, ConstantAddress Addr)
Emit code to cause the destruction of the given variable with static storage duration.
static void EmitDeclInvariant(CodeGenFunction &CGF, const VarDecl &D, llvm::Constant *Addr)
Emit code to cause the variable at the given address to be considered as constant from this point onw...
Defines the clang::LangOptions interface.
const LangOptions & getLangOpts() const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
unsigned getTargetAddressSpace(LangAS AS) const
Represents a C++ destructor within a class.
Represents a C++ struct/union/class.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
static AggValueSlot forLValue(const LValue &LV, CodeGenFunction &CGF, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
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 bool useSinitAndSterm() const
virtual void EmitGuardedInit(CodeGenFunction &CGF, const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)=0
Emits the guarded initializer and destructor setup for the given variable, given that it couldn't be ...
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
virtual bool canCallMismatchedFunctionType() const
Returns true if the target allows calling a function through a pointer with a different signature tha...
virtual void EmitThreadLocalInitFuncs(CodeGenModule &CGM, ArrayRef< const VarDecl * > CXXThreadLocals, ArrayRef< llvm::Function * > CXXThreadLocalInits, ArrayRef< const VarDecl * > CXXThreadLocalInitVars)=0
Emits ABI-required functions necessary to initialize thread_local variables in this translation unit.
MangleContext & getMangleContext()
Gets the mangle context.
CGFunctionInfo - Class to encapsulate the information about a function definition.
void annotateHLSLResource(const VarDecl *D, llvm::GlobalVariable *GV)
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0
virtual llvm::Function * emitThreadPrivateVarDefinition(const VarDecl *VD, Address VDAddr, SourceLocation Loc, bool PerformInit, CodeGenFunction *CGF=nullptr)
Emit a code for initialization of threadprivate variable.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
llvm::Value * EmitObjCAutoreleasePoolPush()
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 EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Type * ConvertTypeForMem(QualType T)
llvm::Function * createTLSAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr, llvm::FunctionCallee &AtExit)
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
void registerGlobalDtorWithLLVM(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Registers the dtor using 'llvm.global_dtors' for platforms that do not support an 'atexit()' function...
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
llvm::Function * generateDestroyHelper(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray, const VarDecl *VD)
void GenerateCXXGlobalCleanUpFunc(llvm::Function *Fn, ArrayRef< std::tuple< llvm::FunctionType *, llvm::WeakTrackingVH, llvm::Constant * > > DtorsOrStermFinalizers)
GenerateCXXGlobalCleanUpFunc - Generates code for cleaning up global variables.
void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)
Emit code in this function to perform a guarded variable initialization.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
void StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const CGFunctionInfo &FnInfo, const FunctionArgList &Args, SourceLocation Loc=SourceLocation(), SourceLocation StartLoc=SourceLocation())
Emit code for the start of a function.
llvm::Function * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
llvm::Value * unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub)
Call unatexit() with function dtorStub.
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind.
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
void EmitInvariantStart(llvm::Constant *Addr, CharUnits Size)
CodeGenTypes & getTypes() const
void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D, llvm::GlobalVariable *Addr, bool PerformInit)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)
llvm::LLVMContext & getLLVMContext()
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitCXXGuardedInitBranch(llvm::Value *NeedsInit, llvm::BasicBlock *InitBlock, llvm::BasicBlock *NoInitBlock, GuardKind Kind, const VarDecl *D)
Emit a branch to select whether or not to perform guarded initialization.
This class organizes the cross-function state that is used while generating LLVM code.
void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
CGHLSLRuntime & getHLSLRuntime()
Return a reference to the configured HLSL runtime.
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
llvm::FunctionCallee getAddrAndTypeOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn, SourceLocation Loc) const
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
const llvm::DataLayout & getDataLayout() const
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
CGCXXABI & getCXXABI() const
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
const llvm::Triple & getTriple() const
void AddGlobalDtor(llvm::Function *Dtor, int Priority=65535, bool IsDtorAttrFunc=false)
AddGlobalDtor - Add a function to the list that will be called when the module is unloaded.
ASTContext & getContext() const
bool supportsCOMDAT() const
const TargetCodeGenInfo & getTargetCodeGenInfo()
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
llvm::GlobalValue * GetGlobalValue(StringRef Ref)
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...
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535, unsigned LexOrder=~0U, llvm::Constant *AssociatedData=nullptr)
AddGlobalCtor - Add a function to the list that will be called before main() runs.
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=std::nullopt)
llvm::Function * CreateGlobalInitOrCleanUpFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false, llvm::GlobalVariable::LinkageTypes Linkage=llvm::GlobalVariable::InternalLinkage)
const CGFunctionInfo & arrangeLLVMFunctionInfo(CanQualType returnType, FnInfoOpts opts, ArrayRef< CanQualType > argTypes, FunctionType::ExtInfo info, ArrayRef< FunctionProtoType::ExtParameterInfo > paramInfos, RequiredArgs args)
"Arrange" the LLVM information for a call or type with the given signature.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
unsigned getTargetAddressSpace(QualType T) const
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
A specialization of Address that requires the address to be an LLVM Constant.
ConstantAddress withElementType(llvm::Type *ElemTy) const
static ConstantAddress invalid()
llvm::Constant * getPointer() const
FunctionArgList - Type for representing both the decl and type of parameters to a function.
LValue - This represents an lvalue references.
bool isObjCStrong() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
virtual LangAS getAddrSpaceOfCxaAtexitPtrParam() const
Get address space of pointer parameter for __cxa_atexit.
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
A class which abstracts out some details necessary for making a call.
GlobalDecl - represents a global declaration.
virtual void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &)=0
virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &)=0
Describes a module or submodule.
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
bool isNamedModuleInterfaceHasInit() const
bool isInterfaceOrPartition() const
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
llvm::iterator_range< submodule_iterator > submodules()
bool isHeaderLikeModule() const
Is this module have similar semantics as headers.
bool isExternallyVisible() const
A (possibly-)qualified type.
@ DK_objc_strong_lifetime
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
LangAS getAddressSpace() const
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
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 isReferenceType() const
Represents a variable declaration or definition.
TLSKind getTLSKind() const
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
@ TLS_Dynamic
TLS with a dynamic initializer.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
@ Dtor_Complete
Complete object dtor.
LLVM_READONLY bool isPreprocessingNumberBody(unsigned char c)
Return true if this is the body character of a C preprocessing number, which is [a-zA-Z0-9_.
@ Other
Other implicit parameter.
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int64Ty
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::CallingConv::ID getRuntimeCC() const
llvm::IntegerType * IntTy
int
llvm::PointerType * Int8PtrTy