22#include "llvm/ADT/StringExtras.h"
23#include "llvm/IR/Intrinsics.h"
24#include "llvm/IR/MDBuilder.h"
25#include "llvm/Support/Path.h"
28using namespace CodeGen;
33 (
D.hasGlobalStorage() ||
35 "VarDecl must have global or local (in the case of OpenCL) storage!");
36 assert(!
D.getType()->isReferenceType() &&
37 "Should not call EmitDeclInit on a reference!");
48 DeclPtr,
D.getTLSKind());
67 llvm_unreachable(
"bad evaluation kind");
95 assert(!
D.getTLSKind() &&
"should have rejected this");
99 llvm::FunctionCallee
Func;
100 llvm::Constant *Argument;
110 bool CanRegisterDestructor =
118 if (
Record && (CanRegisterDestructor || UsingExternalHelper)) {
119 assert(!
Record->hasTrivialDestructor());
126 auto DestTy = llvm::PointerType::get(
128 auto SrcAS =
D.getType().getQualifiers().getAddressSpace();
130 Argument =
Addr.getPointer();
134 Argument = llvm::ConstantPointerNull::get(DestTy);
136 Argument =
Addr.getPointer();
144 Argument = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
153 llvm::Constant *
Addr) {
164 llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
166 assert(
Addr->getType()->isPointerTy() &&
"Address must be a pointer");
167 llvm::Type *ObjectPtr[1] = {
Addr->getType()};
168 llvm::Function *InvariantStart =
CGM.
getIntrinsic(InvStartID, ObjectPtr);
171 uint64_t Width = Size.getQuantity();
172 llvm::Value *Args[2] = {llvm::ConstantInt::getSigned(
Int64Ty, Width),
Addr};
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 =
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(),
221 if (
D.getType().isConstantStorage(
getContext(),
true, !NeedsDtor))
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());
279 const VarDecl &
D, llvm::FunctionCallee Dtor, llvm::Constant *
Addr,
280 llvm::FunctionCallee &
AtExit) {
283 llvm::raw_svector_ostream Out(FnName);
292 llvm::FunctionType *StubTy =
293 llvm::FunctionType::get(
CGM.
IntTy, {CGM.IntTy},
true);
303 Args.push_back(&IPD);
312 llvm::CallInst *call = CGF.
Builder.CreateCall(Dtor,
Addr);
315 if (
auto *DtorFn = dyn_cast<llvm::Function>(
316 Dtor.getCallee()->stripPointerCastsAndAliases()))
317 call->setCallingConv(DtorFn->getCallingConv());
330 llvm::FunctionCallee dtor,
331 llvm::Constant *addr) {
339 llvm::FunctionCallee Dtor,
340 llvm::Constant *
Addr) {
342 llvm::Function *dtorStub =
349 assert(dtorStub->getType()->isPointerTy() &&
350 "Argument to atexit has a wrong type.");
352 llvm::FunctionType *atexitTy =
353 llvm::FunctionType::get(
IntTy, dtorStub->getType(),
false);
355 llvm::FunctionCallee atexit =
358 if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee()))
359 atexitFn->setDoesNotThrow();
373 assert(dtorStub->getType()->isPointerTy() &&
374 "Argument to unatexit has a wrong type.");
376 llvm::FunctionType *unatexitTy =
377 llvm::FunctionType::get(
IntTy, {dtorStub->getType()},
false);
379 llvm::FunctionCallee unatexit =
382 cast<llvm::Function>(unatexit.getCallee())->setDoesNotThrow();
388 llvm::GlobalVariable *DeclPtr,
395 "this initialization requires a guard variable, which "
396 "the kernel does not support");
402 llvm::BasicBlock *InitBlock,
403 llvm::BasicBlock *NoInitBlock,
410 static const uint64_t InitsPerTLSVar = 1024;
411 static const uint64_t InitsPerLocalVar = 1024 * 1024;
413 llvm::MDNode *Weights;
425 NumInits = InitsPerTLSVar;
427 NumInits = InitsPerLocalVar;
432 Weights = MDHelper.createBranchWeights(1, NumInits - 1);
435 Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);
439 llvm::FunctionType *FTy,
const Twine &Name,
const CGFunctionInfo &FI,
441 llvm::Function *Fn = llvm::Function::Create(FTy,
Linkage, Name, &
getModule());
445 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
446 Fn->setSection(Section);
449 if (
Linkage == llvm::GlobalVariable::InternalLinkage)
460 Fn->setDoesNotThrow();
462 if (
getLangOpts().Sanitize.has(SanitizerKind::Address) &&
464 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
466 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&
468 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
470 if (
getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&
472 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
474 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) &&
476 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
478 if (
getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&
480 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
482 if (
getLangOpts().Sanitize.has(SanitizerKind::Type) &&
484 Fn->addFnAttr(llvm::Attribute::SanitizeType);
486 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
488 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
490 if (
getLangOpts().Sanitize.has(SanitizerKind::NumericalStability) &&
492 Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
494 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
496 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
498 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) &&
500 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
502 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
504 Fn->addFnAttr(llvm::Attribute::SafeStack);
506 if (
getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) &&
508 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
516void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *
D,
517 llvm::GlobalVariable *GV,
518 llvm::Function *InitFunc,
520 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
521 TheModule, InitFunc->getType(),
true,
522 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
523 PtrArray->setSection(ISA->getSection());
527 if (llvm::Comdat *
C = GV->getComdat())
528 PtrArray->setComdat(
C);
532CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *
D,
533 llvm::GlobalVariable *
Addr,
547 auto I = DelayedCXXInitPosition.find(
D);
548 if (I != DelayedCXXInitPosition.end() && I->second == ~0
U)
551 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
554 llvm::raw_svector_ostream Out(FnName);
562 auto *ISA =
D->
getAttr<InitSegAttr>();
566 llvm::GlobalVariable *COMDATKey =
569 if (
D->getTLSKind()) {
573 CXXThreadLocalInits.push_back(Fn);
574 CXXThreadLocalInitVars.push_back(
D);
575 }
else if (PerformInit && ISA) {
579 if (ISA->getSection() ==
".CRT$XCC")
581 else if (ISA->getSection() ==
".CRT$XCL")
587 EmitPointerToInitFunc(
D,
Addr, Fn, ISA);
588 }
else if (
auto *IPA =
D->
getAttr<InitPriorityAttr>()) {
590 PrioritizedCXXGlobalInits.size());
591 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
636 I = DelayedCXXInitPosition.find(
D);
638 I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;
640 if (COMDATKey && (
getTriple().isOSBinFormatELF() ||
650 llvm::Comdat *
C =
Addr->getComdat();
651 if (COMDATKey &&
C &&
657 I = DelayedCXXInitPosition.find(
D);
658 if (I == DelayedCXXInitPosition.end()) {
659 CXXGlobalInits.push_back(Fn);
660 }
else if (I->second != ~0
U) {
661 assert(I->second < CXXGlobalInits.size() &&
662 CXXGlobalInits[I->second] ==
nullptr);
663 CXXGlobalInits[I->second] =
Fn;
668 DelayedCXXInitPosition[
D] = ~0
U;
671void CodeGenModule::EmitCXXThreadLocalInitFunc() {
673 *
this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
675 CXXThreadLocalInits.clear();
676 CXXThreadLocalInitVars.clear();
677 CXXThreadLocals.clear();
695void CodeGenModule::EmitCXXModuleInitFunc(
Module *Primary) {
697 "The function should only be called for C++20 named module interface"
700 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
701 CXXGlobalInits.pop_back();
709 for (
auto I : Primary->
Exports)
710 AllImports.insert(I.getPointer());
712 AllImports.insert_range(Primary->
Imports);
716 assert((SubM->isGlobalModule() || SubM->isPrivateModule()) &&
717 "The sub modules of C++20 module unit should only be global module "
718 "fragments or private module framents.");
719 assert(SubM->Exports.empty() &&
720 "The global mdoule fragments and the private module fragments are "
721 "not allowed to export import modules.");
722 AllImports.insert_range(SubM->Imports);
726 for (
Module *M : AllImports) {
728 if (M->isHeaderLikeModule())
732 if (!M->isNamedModuleInterfaceHasInit())
734 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
737 llvm::raw_svector_ostream Out(FnName);
738 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
739 .mangleModuleInitializer(M, Out);
742 "We should only have one use of the initializer call");
743 llvm::Function *
Fn = llvm::Function::Create(
744 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
745 ModuleInits.push_back(Fn);
750 if (!PrioritizedCXXGlobalInits.empty()) {
751 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
752 PrioritizedCXXGlobalInits.end());
754 I = PrioritizedCXXGlobalInits.begin(),
755 E = PrioritizedCXXGlobalInits.end();
758 std::upper_bound(I + 1,
E, *I, GlobalInitPriorityCmp());
760 for (; I < PrioE; ++I)
761 ModuleInits.push_back(I->second);
766 for (
auto *F : CXXGlobalInits)
767 ModuleInits.push_back(F);
769 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
779 llvm::raw_svector_ostream Out(InitFnName);
780 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
781 .mangleModuleInitializer(Primary, Out);
784 llvm::GlobalVariable::ExternalLinkage);
789 if (!ModuleInits.empty()) {
791 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
793 llvm::GlobalVariable::InternalLinkage,
794 llvm::ConstantInt::get(
Int8Ty, 0), InitFnName.str() +
"__in_chrg");
813 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
820 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
822 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
823 Fn->addFnAttr(
"device-init");
828 PrioritizedCXXGlobalInits.clear();
829 CXXGlobalInits.clear();
839 for (
size_t i = 0; i <
FileName.size(); ++i) {
850 assert(
Priority <= 65535 &&
"Priority should always be <= 65535.");
854 std::string PrioritySuffix = llvm::utostr(
Priority);
855 PrioritySuffix = std::string(6 - PrioritySuffix.size(),
'0') + PrioritySuffix;
857 return PrioritySuffix;
861CodeGenModule::EmitCXXGlobalInitFunc() {
862 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
863 CXXGlobalInits.pop_back();
867 if (CXX20ModuleInits)
868 for (
Module *M : ImportedModules) {
870 if (M->isHeaderLikeModule())
874 if (!M->isNamedModuleInterfaceHasInit())
876 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
879 llvm::raw_svector_ostream Out(FnName);
880 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
881 .mangleModuleInitializer(M, Out);
884 "We should only have one use of the initializer call");
885 llvm::Function *
Fn = llvm::Function::Create(
886 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
887 ModuleInits.push_back(Fn);
890 if (ModuleInits.empty() && CXXGlobalInits.empty() &&
891 PrioritizedCXXGlobalInits.empty())
894 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
898 if (!PrioritizedCXXGlobalInits.empty()) {
900 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
901 PrioritizedCXXGlobalInits.end());
906 I = PrioritizedCXXGlobalInits.begin(),
907 E = PrioritizedCXXGlobalInits.end(); I !=
E; ) {
909 PrioE = std::upper_bound(I + 1,
E, *I, GlobalInitPriorityCmp());
911 LocalCXXGlobalInits.clear();
913 unsigned int Priority = I->first.priority;
918 if (!ModuleInits.empty()) {
919 for (
auto *F : ModuleInits)
920 LocalCXXGlobalInits.push_back(F);
924 for (; I < PrioE; ++I)
925 LocalCXXGlobalInits.push_back(I->second);
930 PrioritizedCXXGlobalInits.clear();
933 if (
getCXXABI().useSinitAndSterm() && ModuleInits.empty() &&
934 CXXGlobalInits.empty())
937 for (
auto *F : CXXGlobalInits)
938 ModuleInits.push_back(F);
939 CXXGlobalInits.clear();
946 if (CXX20ModuleInits &&
getContext().getCurrentNamedModule() &&
947 !
getContext().getCurrentNamedModule()->isModuleImplementation()) {
949 llvm::raw_svector_ostream Out(InitFnName);
950 cast<ItaniumMangleContext>(
getCXXABI().getMangleContext())
951 .mangleModuleInitializer(
getContext().getCurrentNamedModule(), Out);
954 llvm::GlobalVariable::ExternalLinkage);
974 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
981 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
983 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
984 Fn->addFnAttr(
"device-init");
990void CodeGenModule::EmitCXXGlobalCleanUpFunc() {
991 if (CXXGlobalDtorsOrStermFinalizers.empty() &&
992 PrioritizedCXXStermFinalizers.empty())
995 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
999 if (!PrioritizedCXXStermFinalizers.empty()) {
1001 llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(),
1002 PrioritizedCXXStermFinalizers.end());
1007 I = PrioritizedCXXStermFinalizers.begin(),
1008 E = PrioritizedCXXStermFinalizers.end();
1011 std::upper_bound(I + 1,
E, *I, StermFinalizerPriorityCmp());
1013 LocalCXXStermFinalizers.clear();
1015 unsigned int Priority = I->first.priority;
1019 for (; I < PrioE; ++I) {
1020 llvm::FunctionCallee DtorFn = I->second;
1021 LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),
1022 DtorFn.getCallee(),
nullptr);
1026 Fn, LocalCXXStermFinalizers);
1029 PrioritizedCXXStermFinalizers.clear();
1032 if (CXXGlobalDtorsOrStermFinalizers.empty())
1036 llvm::Function *
Fn =
1040 Fn, CXXGlobalDtorsOrStermFinalizers);
1042 CXXGlobalDtorsOrStermFinalizers.clear();
1048 llvm::GlobalVariable *
Addr,
1052 DebugInfo =
nullptr;
1069 if (
Addr->hasWeakLinkage() ||
Addr->hasLinkOnceLinkage() ||
1091 llvm::BasicBlock *ExitBlock =
nullptr;
1097 "guard.uninitialized");
1124 for (llvm::Function *
Decl : Decls)
1128 Scope.ForceCleanup();
1141 ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
1143 DtorsOrStermFinalizers) {
1152 for (
unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) {
1153 llvm::FunctionType *CalleeTy;
1154 llvm::Value *Callee;
1155 llvm::Constant *Arg;
1156 std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];
1158 llvm::CallBase *CI =
nullptr;
1159 if (Arg ==
nullptr) {
1162 "Arg could not be nullptr unless using sinit and sterm functions.");
1163 CI =
Builder.CreateCall(CalleeTy, Callee);
1168 assert(Arg->getType()->isPointerTy());
1169 assert(CalleeTy->getParamType(0)->isPointerTy());
1170 unsigned ActualAddrSpace = Arg->getType()->getPointerAddressSpace();
1171 unsigned ExpectedAddrSpace =
1172 CalleeTy->getParamType(0)->getPointerAddressSpace();
1173 if (ActualAddrSpace != ExpectedAddrSpace) {
1174 llvm::PointerType *PTy =
1176 Arg = llvm::ConstantExpr::getAddrSpaceCast(Arg, PTy);
1178 CI =
Builder.CreateCall(CalleeTy, Callee, Arg);
1182 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
1183 CI->setCallingConv(F->getCallingConv());
1186 CI = addConvergenceControlToken(CI);
1198 bool useEHCleanupForArray,
const VarDecl *VD) {
1202 args.push_back(&Dst);
1208 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.
llvm::MachO::Record Record
const LangOptions & getLangOpts() const
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
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.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
static AggValueSlot forLValue(const LValue &LV, 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::Value * CreateIsNull(Address Addr, const Twine &Name="")
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.
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.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited.
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)
Emit code in this function to perform a guarded variable initialization.
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
llvm::Function * createTLSAtExitStub(const VarDecl &VD, llvm::FunctionCallee Dtor, llvm::Constant *Addr, llvm::FunctionCallee &AtExit)
Create a stub function, suitable for being passed to __pt_atexit_np, which passes the given address t...
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 registerGlobalDtorWithAtExit(const VarDecl &D, llvm::FunctionCallee fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::GlobalVariable *GV, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
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.
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, ConstantAddress Guard=ConstantAddress::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D, llvm::GlobalVariable *Addr, bool PerformInit)
Emit the code necessary to initialize the given global variable.
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.
void EmitInvariantStart(llvm::Constant *Addr, CharUnits Size)
llvm::Value * unregisterGlobalDtorWithUnAtExit(llvm::Constant *dtorStub)
Call unatexit() with function dtorStub.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
ASTContext & getContext() const
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...
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="")
llvm::Type * ConvertTypeForMem(QualType T)
void GenerateCXXGlobalCleanUpFunc(llvm::Function *Fn, ArrayRef< std::tuple< llvm::FunctionType *, llvm::WeakTrackingVH, llvm::Constant * > > DtorsOrStermFinalizers)
GenerateCXXGlobalCleanUpFunc - Generates code for cleaning up global variables.
llvm::Value * EmitObjCAutoreleasePoolPush()
Produce the code to do a objc_autoreleasepool_push.
CodeGenTypes & getTypes() const
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
llvm::Function * generateDestroyHelper(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray, const VarDecl *VD)
generateDestroyHelper - Generates a helper function which, when invoked, destroys the given object.
Address ReturnValue
ReturnValue - The temporary alloca to hold the return value.
llvm::LLVMContext & getLLVMContext()
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 EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
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.
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)
llvm::Constant * getFunctionPointer(GlobalDecl GD, llvm::Type *Ty=nullptr)
Return the ABI-correct function pointer value for a reference to the given function.
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.
bool shouldEmitConvergenceTokens() const
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...
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
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.
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
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.
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 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const
setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...
virtual LangAS getAddrSpaceOfCxaAtexitPtrParam() const
Get address space of pointer parameter for __cxa_atexit.
Decl - This represents one declaration (or definition), e.g.
SourceLocation getLocation() const
SourceLocation getBeginLoc() const LLVM_READONLY
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 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()
A (possibly-)qualified type.
@ DK_objc_strong_lifetime
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.
const Expr * getInit() const
@ TLS_Dynamic
TLS with a dynamic initializer.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
bool isUniqueGVALinkage(GVALinkage L)
Do we know that this will be the only definition of this symbol (excluding inlining-only definitions)...
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_.
const FunctionProtoType * T
@ 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
Extra information about a function prototype.