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());
129 Argument = llvm::ConstantExpr::getBitCast(Addr.
getPointer(), DestTy);
133 Argument = llvm::ConstantPointerNull::get(DestTy);
135 Argument = llvm::ConstantExpr::getBitCast(
144 Argument = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
153 llvm::Constant *Addr) {
158void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr,
CharUnits Size) {
164 llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
167 llvm::Function *InvariantStart =
CGM.
getIntrinsic(InvStartID, ObjectPtr);
171 llvm::Value *Args[2] = { llvm::ConstantInt::getSigned(
Int64Ty, Width),
172 llvm::ConstantExpr::getBitCast(Addr,
Int8PtrTy)};
173 Builder.CreateCall(InvariantStart, Args);
177 llvm::GlobalVariable *GV,
199 unsigned ActualAddrSpace = GV->getAddressSpace();
200 llvm::Constant *DeclPtr = GV;
201 if (ActualAddrSpace != ExpectedAddrSpace) {
202 llvm::PointerType *PTy = llvm::PointerType::getWithSamePointeeType(
203 GV->getType(), ExpectedAddrSpace);
204 DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
208 DeclPtr, GV->getValueType(),
getContext().getDeclAlign(&D));
212 D.
hasAttr<OMPThreadPrivateDeclAttr>()) {
214 &D, DeclAddr, D.
getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
228 assert(PerformInit &&
"cannot have constant initializer which needs "
229 "destruction for reference");
237 llvm::FunctionCallee dtor,
238 llvm::Constant *addr) {
240 llvm::FunctionType *ty = llvm::FunctionType::get(
CGM.
VoidTy,
false);
243 llvm::raw_svector_ostream Out(FnName);
259 llvm::CallInst *call = CGF.Builder.CreateCall(dtor, addr);
262 if (
auto *dtorFn = dyn_cast<llvm::Function>(
263 dtor.getCallee()->stripPointerCastsAndAliases()))
264 call->setCallingConv(dtorFn->getCallingConv());
266 CGF.FinishFunction();
274 const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *Addr,
275 llvm::FunctionCallee &
AtExit) {
278 llvm::raw_svector_ostream Out(FnName);
287 llvm::FunctionType *StubTy =
288 llvm::FunctionType::get(
CGM.
IntTy, {CGM.IntTy},
true);
298 Args.push_back(&IPD);
307 llvm::CallInst *call = CGF.Builder.CreateCall(Dtor, Addr);
310 if (
auto *DtorFn = dyn_cast<llvm::Function>(
311 Dtor.getCallee()->stripPointerCastsAndAliases()))
312 call->setCallingConv(DtorFn->getCallingConv());
315 CGF.Builder.CreateStore(llvm::Constant::getNullValue(
CGM.
IntTy),
318 CGF.FinishFunction();
325 llvm::FunctionCallee dtor,
326 llvm::Constant *addr) {
334 assert(dtorStub->getType() ==
335 llvm::PointerType::get(
336 llvm::FunctionType::get(
CGM.
VoidTy,
false),
337 dtorStub->getType()->getPointerAddressSpace()) &&
338 "Argument to atexit has a wrong type.");
340 llvm::FunctionType *atexitTy =
341 llvm::FunctionType::get(
IntTy, dtorStub->getType(),
false);
343 llvm::FunctionCallee atexit =
346 if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee()))
347 atexitFn->setDoesNotThrow();
361 assert(dtorStub->getType() ==
362 llvm::PointerType::get(
363 llvm::FunctionType::get(
CGM.
VoidTy,
false),
364 dtorStub->getType()->getPointerAddressSpace()) &&
365 "Argument to unatexit has a wrong type.");
367 llvm::FunctionType *unatexitTy =
368 llvm::FunctionType::get(
IntTy, {dtorStub->getType()},
false);
370 llvm::FunctionCallee unatexit =
373 cast<llvm::Function>(unatexit.getCallee())->setDoesNotThrow();
379 llvm::GlobalVariable *DeclPtr,
386 "this initialization requires a guard variable, which "
387 "the kernel does not support");
393 llvm::BasicBlock *InitBlock,
394 llvm::BasicBlock *NoInitBlock,
401 static const uint64_t InitsPerTLSVar = 1024;
402 static const uint64_t InitsPerLocalVar = 1024 * 1024;
404 llvm::MDNode *Weights;
416 NumInits = InitsPerTLSVar;
418 NumInits = InitsPerLocalVar;
423 Weights = MDHelper.createBranchWeights(1, NumInits - 1);
426 Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);
430 llvm::FunctionType *FTy,
const Twine &Name,
const CGFunctionInfo &FI,
432 llvm::Function *Fn = llvm::Function::Create(FTy,
Linkage, Name, &
getModule());
436 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
437 Fn->setSection(Section);
440 if (
Linkage == llvm::GlobalVariable::InternalLinkage)
446 Fn->setDoesNotThrow();
448 if (
getLangOpts().Sanitize.has(SanitizerKind::Address) &&
450 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
452 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&
454 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
456 if (
getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&
458 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
460 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) &&
462 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
464 if (
getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&
466 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
468 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
470 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
472 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
474 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
476 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) &&
478 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
480 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
482 Fn->addFnAttr(llvm::Attribute::SafeStack);
484 if (
getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) &&
486 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
494void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *D,
495 llvm::GlobalVariable *GV,
496 llvm::Function *InitFunc,
498 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
499 TheModule, InitFunc->getType(),
true,
500 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
501 PtrArray->setSection(ISA->getSection());
505 if (llvm::Comdat *
C = GV->getComdat())
506 PtrArray->setComdat(
C);
510CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *D,
511 llvm::GlobalVariable *Addr,
520 (D->
hasAttr<CUDADeviceAttr>() || D->
hasAttr<CUDAConstantAttr>() ||
529 auto I = DelayedCXXInitPosition.find(D);
530 if (I != DelayedCXXInitPosition.end() && I->second == ~0
U)
533 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
536 llvm::raw_svector_ostream Out(FnName);
544 auto *ISA = D->
getAttr<InitSegAttr>();
548 llvm::GlobalVariable *COMDATKey =
555 CXXThreadLocalInits.push_back(Fn);
556 CXXThreadLocalInitVars.push_back(D);
557 }
else if (PerformInit && ISA) {
561 if (ISA->getSection() ==
".CRT$XCC")
563 else if (ISA->getSection() ==
".CRT$XCL")
567 AddGlobalCtor(Fn, Priority, ~0
U, COMDATKey);
569 EmitPointerToInitFunc(D, Addr, Fn, ISA);
570 }
else if (
auto *IPA = D->
getAttr<InitPriorityAttr>()) {
572 PrioritizedCXXGlobalInits.size());
573 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
593 I = DelayedCXXInitPosition.find(D);
601 I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;
602 AddGlobalCtor(Fn, 65535, LexOrder, COMDATKey);
603 if (COMDATKey && (
getTriple().isOSBinFormatELF() ||
613 llvm::Comdat *
C = Addr->getComdat();
614 if (COMDATKey &&
C &&
620 I = DelayedCXXInitPosition.find(D);
621 if (I == DelayedCXXInitPosition.end()) {
622 CXXGlobalInits.push_back(Fn);
623 }
else if (I->second != ~0
U) {
624 assert(I->second < CXXGlobalInits.size() &&
625 CXXGlobalInits[I->second] ==
nullptr);
626 CXXGlobalInits[I->second] = Fn;
631 DelayedCXXInitPosition[D] = ~0
U;
634void CodeGenModule::EmitCXXThreadLocalInitFunc() {
636 *
this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
638 CXXThreadLocalInits.clear();
639 CXXThreadLocalInitVars.clear();
640 CXXThreadLocals.clear();
658void CodeGenModule::EmitCXXModuleInitFunc(
Module *Primary) {
659 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
660 CXXGlobalInits.pop_back();
668 for (
auto I : Primary->
Exports)
669 AllImports.push_back(I.getPointer());
672 AllImports.push_back(M);
675 for (
Module *M : AllImports) {
679 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
682 llvm::raw_svector_ostream Out(FnName);
683 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
684 .mangleModuleInitializer(M, Out);
687 "We should only have one use of the initializer call");
688 llvm::Function *Fn = llvm::Function::Create(
689 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
690 ModuleInits.push_back(Fn);
695 if (!PrioritizedCXXGlobalInits.empty()) {
697 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
698 PrioritizedCXXGlobalInits.end());
700 I = PrioritizedCXXGlobalInits.begin(),
701 E = PrioritizedCXXGlobalInits.end();
704 std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
706 for (; I < PrioE; ++I)
707 ModuleInits.push_back(I->second);
712 for (
auto *F : CXXGlobalInits)
713 ModuleInits.push_back(F);
715 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
725 llvm::raw_svector_ostream Out(InitFnName);
726 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
727 .mangleModuleInitializer(Primary, Out);
730 llvm::GlobalVariable::ExternalLinkage);
735 if (!AllImports.empty() || !PrioritizedCXXGlobalInits.empty() ||
736 !CXXGlobalInits.empty()) {
738 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
740 llvm::GlobalVariable::InternalLinkage,
741 llvm::ConstantInt::get(
Int8Ty, 0), InitFnName.str() +
"__in_chrg");
760 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
766 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
767 Fn->addFnAttr(
"device-init");
772 PrioritizedCXXGlobalInits.clear();
773 CXXGlobalInits.clear();
780 if (FileName.empty())
783 for (
size_t i = 0; i < FileName.size(); ++i) {
794 assert(
Priority <= 65535 &&
"Priority should always be <= 65535.");
798 std::string PrioritySuffix = llvm::utostr(
Priority);
799 PrioritySuffix = std::string(6 - PrioritySuffix.size(),
'0') + PrioritySuffix;
801 return PrioritySuffix;
805CodeGenModule::EmitCXXGlobalInitFunc() {
806 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
807 CXXGlobalInits.pop_back();
811 if (CXX20ModuleInits)
812 for (
Module *M : ImportedModules) {
816 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
819 llvm::raw_svector_ostream Out(FnName);
820 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
821 .mangleModuleInitializer(M, Out);
824 "We should only have one use of the initializer call");
825 llvm::Function *Fn = llvm::Function::Create(
826 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
827 ModuleInits.push_back(Fn);
830 if (ModuleInits.empty() && CXXGlobalInits.empty() &&
831 PrioritizedCXXGlobalInits.empty())
834 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
838 if (!PrioritizedCXXGlobalInits.empty()) {
840 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
841 PrioritizedCXXGlobalInits.end());
846 I = PrioritizedCXXGlobalInits.begin(),
847 E = PrioritizedCXXGlobalInits.end(); I != E; ) {
849 PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
851 LocalCXXGlobalInits.clear();
853 unsigned int Priority = I->first.priority;
858 if (!ModuleInits.empty()) {
859 for (
auto *F : ModuleInits)
860 LocalCXXGlobalInits.push_back(F);
864 for (; I < PrioE; ++I)
865 LocalCXXGlobalInits.push_back(I->second);
868 AddGlobalCtor(Fn, Priority);
870 PrioritizedCXXGlobalInits.clear();
873 if (
getCXXABI().useSinitAndSterm() && ModuleInits.empty() &&
874 CXXGlobalInits.empty())
877 for (
auto *F : CXXGlobalInits)
878 ModuleInits.push_back(F);
879 CXXGlobalInits.clear();
886 if (CXX20ModuleInits &&
getContext().getNamedModuleForCodeGen() &&
887 !
getContext().getNamedModuleForCodeGen()->isModuleImplementation()) {
889 llvm::raw_svector_ostream Out(InitFnName);
890 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
891 .mangleModuleInitializer(
getContext().getNamedModuleForCodeGen(), Out);
894 llvm::GlobalVariable::ExternalLinkage);
914 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
920 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
921 Fn->addFnAttr(
"device-init");
927void CodeGenModule::EmitCXXGlobalCleanUpFunc() {
928 if (CXXGlobalDtorsOrStermFinalizers.empty() &&
929 PrioritizedCXXStermFinalizers.empty())
932 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
936 if (!PrioritizedCXXStermFinalizers.empty()) {
938 llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(),
939 PrioritizedCXXStermFinalizers.end());
944 I = PrioritizedCXXStermFinalizers.begin(),
945 E = PrioritizedCXXStermFinalizers.end();
948 std::upper_bound(I + 1, E, *I, StermFinalizerPriorityCmp());
950 LocalCXXStermFinalizers.clear();
952 unsigned int Priority = I->first.priority;
956 for (; I < PrioE; ++I) {
957 llvm::FunctionCallee DtorFn = I->second;
958 LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),
959 DtorFn.getCallee(),
nullptr);
963 Fn, LocalCXXStermFinalizers);
964 AddGlobalDtor(Fn, Priority);
966 PrioritizedCXXStermFinalizers.clear();
969 if (CXXGlobalDtorsOrStermFinalizers.empty())
977 Fn, CXXGlobalDtorsOrStermFinalizers);
979 CXXGlobalDtorsOrStermFinalizers.clear();
985 llvm::GlobalVariable *Addr,
1006 if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage() ||
1031 llvm::BasicBlock *ExitBlock =
nullptr;
1036 llvm::Value *Uninit =
Builder.CreateIsNull(GuardVal,
1037 "guard.uninitialized");
1055 RunCleanupsScope
Scope(*
this);
1064 for (
unsigned i = 0, e = Decls.size(); i != e; ++i)
1068 Scope.ForceCleanup();
1081 ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
1083 DtorsOrStermFinalizers) {
1092 for (
unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) {
1093 llvm::FunctionType *CalleeTy;
1095 llvm::Constant *Arg;
1096 std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];
1098 llvm::CallInst *CI =
nullptr;
1099 if (Arg ==
nullptr) {
1102 "Arg could not be nullptr unless using sinit and sterm functions.");
1103 CI =
Builder.CreateCall(CalleeTy, Callee);
1105 CI =
Builder.CreateCall(CalleeTy, Callee, Arg);
1108 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
1109 CI->setCallingConv(F->getCallingConv());
1121 bool useEHCleanupForArray,
const VarDecl *VD) {
1125 args.push_back(&Dst);
1131 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)
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::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
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...
bool isTypeConstant(QualType QTy, bool ExcludeCtor, bool ExcludeDtor)
isTypeConstant - Determine whether an object of this type can be emitted as a constant.
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
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, bool instanceMethod, bool chainCall, 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::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
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 getElementBitCast(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.
@ Other
Other implicit parameter.
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.
llvm::SmallSetVector< Module *, 2 > Imports
The set of modules imported by this module, and on which this module depends.
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.
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.
@ C
Languages that the frontend can parse and compile.
@ 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_.
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