23#include "llvm/ADT/StringExtras.h"
24#include "llvm/IR/Intrinsics.h"
25#include "llvm/IR/MDBuilder.h"
26#include "llvm/Support/Path.h"
36 "VarDecl must have global or local (in the case of OpenCL) storage!");
38 "Should not call EmitDeclInit on a reference!");
47 if (lv.isObjCStrong())
50 else if (lv.isObjCWeak())
68 llvm_unreachable(
"bad evaluation kind");
96 assert(!D.
getTLSKind() &&
"should have rejected this");
100 llvm::FunctionCallee
Func;
101 llvm::Constant *Argument;
111 bool CanRegisterDestructor =
119 if (
Record && (CanRegisterDestructor || UsingExternalHelper)) {
120 assert(!
Record->hasTrivialDestructor());
127 auto DestTy = llvm::PointerType::get(
131 Argument =
Addr.getPointer();
135 Argument = llvm::ConstantPointerNull::get(DestTy);
137 Argument =
Addr.getPointer();
145 Argument = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
154 llvm::Constant *
Addr) {
161 if (!
CGM.getCodeGenOpts().OptimizationLevel)
165 llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
167 assert(
Addr->getType()->isPointerTy() &&
"Address must be a pointer");
168 llvm::Type *ObjectPtr[1] = {
Addr->getType()};
169 llvm::Function *InvariantStart =
CGM.getIntrinsic(InvStartID, ObjectPtr);
172 uint64_t Width = Size.getQuantity();
173 llvm::Value *Args[2] = {llvm::ConstantInt::getSigned(
Int64Ty, Width),
Addr};
174 Builder.CreateCall(InvariantStart, Args);
178 llvm::GlobalVariable *GV,
200 unsigned ActualAddrSpace = GV->getAddressSpace();
201 llvm::Constant *DeclPtr = GV;
202 if (ActualAddrSpace != ExpectedAddrSpace) {
203 llvm::PointerType *PTy =
205 DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
209 DeclPtr, GV->getValueType(),
getContext().getDeclAlign(&D));
211 if (!
T->isReferenceType()) {
213 D.
hasAttr<OMPThreadPrivateDeclAttr>()) {
214 (void)
CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition(
215 &D, DeclAddr, D.
getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
229 assert(PerformInit &&
"cannot have constant initializer which needs "
230 "destruction for reference");
238 llvm::FunctionCallee dtor,
239 llvm::Constant *addr) {
241 llvm::FunctionType *ty = llvm::FunctionType::get(
CGM.VoidTy,
false);
244 llvm::raw_svector_ostream Out(FnName);
245 CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out);
249 llvm::Function *fn =
CGM.CreateGlobalInitOrCleanUpFunction(
252 CodeGenFunction CGF(
CGM);
260 llvm::CallInst *call = CGF.
Builder.CreateCall(dtor, addr);
263 if (
auto *dtorFn = dyn_cast<llvm::Function>(
264 dtor.getCallee()->stripPointerCastsAndAliases()))
265 call->setCallingConv(dtorFn->getCallingConv());
274 return CGM.getFunctionPointer(fn, fnType);
280 const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *
Addr,
281 llvm::FunctionCallee &
AtExit) {
284 llvm::raw_svector_ostream Out(FnName);
285 CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&D, Out);
294 llvm::FunctionType *StubTy =
295 llvm::FunctionType::get(
CGM.IntTy, {CGM.IntTy},
true);
297 llvm::Function *DtorStub =
CGM.CreateGlobalInitOrCleanUpFunction(
300 CodeGenFunction CGF(
CGM);
313 llvm::CallInst *call = CGF.
Builder.CreateCall(Dtor,
Addr);
316 if (
auto *DtorFn = dyn_cast<llvm::Function>(
317 Dtor.getCallee()->stripPointerCastsAndAliases()))
318 call->setCallingConv(DtorFn->getCallingConv());
331 llvm::FunctionCallee dtor,
332 llvm::Constant *addr) {
340 llvm::FunctionCallee Dtor,
341 llvm::Constant *
Addr) {
343 llvm::Function *dtorStub =
345 CGM.AddGlobalDtor(dtorStub);
350 assert(dtorStub->getType()->isPointerTy() &&
351 "Argument to atexit has a wrong type.");
353 llvm::FunctionType *atexitTy =
354 llvm::FunctionType::get(
IntTy, dtorStub->getType(),
false);
356 llvm::FunctionCallee atexit =
357 CGM.CreateRuntimeFunction(atexitTy,
"atexit", llvm::AttributeList(),
359 if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee()))
360 atexitFn->setDoesNotThrow();
374 assert(dtorStub->getType()->isPointerTy() &&
375 "Argument to unatexit has a wrong type.");
377 llvm::FunctionType *unatexitTy =
378 llvm::FunctionType::get(
IntTy, {dtorStub->getType()},
false);
380 llvm::FunctionCallee unatexit =
381 CGM.CreateRuntimeFunction(unatexitTy,
"unatexit", llvm::AttributeList());
389 llvm::GlobalVariable *DeclPtr,
394 if (
CGM.getCodeGenOpts().ForbidGuardVariables)
396 "this initialization requires a guard variable, which "
397 "the kernel does not support");
399 CGM.getCXXABI().EmitGuardedInit(*
this, D, DeclPtr, PerformInit);
403 llvm::BasicBlock *InitBlock,
404 llvm::BasicBlock *NoInitBlock,
411 static const uint64_t InitsPerTLSVar = 1024;
412 static const uint64_t InitsPerLocalVar = 1024 * 1024;
414 llvm::MDNode *Weights;
426 NumInits = InitsPerTLSVar;
428 NumInits = InitsPerLocalVar;
432 llvm::MDBuilder MDHelper(
CGM.getLLVMContext());
433 Weights = MDHelper.createBranchWeights(1, NumInits - 1);
436 Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);
440 llvm::FunctionType *FTy,
const Twine &Name,
const CGFunctionInfo &FI,
442 llvm::Function *Fn = llvm::Function::Create(FTy,
Linkage, Name, &
getModule());
446 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
447 Fn->setSection(Section);
450 if (
Linkage == llvm::GlobalVariable::InternalLinkage)
461 Fn->setDoesNotThrow();
463 if (
getLangOpts().Sanitize.has(SanitizerKind::Address) &&
465 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
467 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&
469 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
471 if (
getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&
473 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
475 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) &&
477 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
479 if (
getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&
481 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
483 if (
getLangOpts().Sanitize.has(SanitizerKind::Type) &&
485 Fn->addFnAttr(llvm::Attribute::SanitizeType);
487 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
489 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
491 if (
getLangOpts().Sanitize.has(SanitizerKind::Concurrency) &&
493 Fn->addFnAttr(llvm::Attribute::SanitizeConcurrency);
495 if (
getLangOpts().Sanitize.has(SanitizerKind::NumericalStability) &&
497 Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
499 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
501 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
503 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) &&
505 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
507 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
509 Fn->addFnAttr(llvm::Attribute::SafeStack);
511 if (
getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) &&
513 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
521void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *D,
522 llvm::GlobalVariable *GV,
523 llvm::Function *InitFunc,
525 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
526 TheModule, InitFunc->getType(),
true,
527 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
528 PtrArray->setSection(ISA->getSection());
532 if (llvm::Comdat *
C = GV->getComdat())
533 PtrArray->setComdat(
C);
537CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *D,
538 llvm::GlobalVariable *
Addr,
547 (D->
hasAttr<CUDADeviceAttr>() || D->
hasAttr<CUDAConstantAttr>() ||
552 auto I = DelayedCXXInitPosition.find(D);
553 if (I != DelayedCXXInitPosition.end() && I->second == ~0
U)
556 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
559 llvm::raw_svector_ostream Out(FnName);
567 auto *ISA = D->
getAttr<InitSegAttr>();
571 llvm::GlobalVariable *COMDATKey =
578 CXXThreadLocalInits.push_back(Fn);
579 CXXThreadLocalInitVars.push_back(D);
580 }
else if (PerformInit && ISA) {
584 if (ISA->getSection() ==
".CRT$XCC")
586 else if (ISA->getSection() ==
".CRT$XCL")
592 EmitPointerToInitFunc(D,
Addr, Fn, ISA);
593 }
else if (
auto *IPA = D->
getAttr<InitPriorityAttr>()) {
594 OrderGlobalInitsOrStermFinalizers Key(IPA->getPriority(),
595 PrioritizedCXXGlobalInits.size());
596 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
641 I = DelayedCXXInitPosition.find(D);
643 I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;
645 if (COMDATKey && (
getTriple().isOSBinFormatELF() ||
655 llvm::Comdat *
C =
Addr->getComdat();
656 if (COMDATKey &&
C &&
662 I = DelayedCXXInitPosition.find(D);
663 if (I == DelayedCXXInitPosition.end()) {
664 CXXGlobalInits.push_back(Fn);
665 }
else if (I->second != ~0U) {
666 assert(I->second < CXXGlobalInits.size() &&
667 CXXGlobalInits[I->second] ==
nullptr);
668 CXXGlobalInits[I->second] =
Fn;
673 DelayedCXXInitPosition[D] = ~0U;
676void CodeGenModule::EmitCXXThreadLocalInitFunc() {
678 *
this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
680 CXXThreadLocalInits.clear();
681 CXXThreadLocalInitVars.clear();
682 CXXThreadLocals.clear();
700void CodeGenModule::EmitCXXModuleInitFunc(
Module *Primary) {
702 "The function should only be called for C++20 named module interface"
705 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
706 CXXGlobalInits.pop_back();
711 SmallVector<llvm::Function *, 8> ModuleInits;
713 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
714 SmallString<256> FnName;
716 llvm::raw_svector_ostream
Out(FnName);
718 .mangleModuleInitializer(M, Out);
721 "We should only have one use of the initializer call");
722 llvm::Function *
Fn = llvm::Function::Create(
723 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
724 ModuleInits.push_back(Fn);
729 if (!PrioritizedCXXGlobalInits.empty()) {
730 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
731 PrioritizedCXXGlobalInits.end());
732 for (SmallVectorImpl<GlobalInitData>::iterator
733 I = PrioritizedCXXGlobalInits.begin(),
734 E = PrioritizedCXXGlobalInits.end();
736 SmallVectorImpl<GlobalInitData>::iterator PrioE =
737 std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
739 for (; I < PrioE; ++I)
740 ModuleInits.push_back(I->second);
745 for (
auto *F : CXXGlobalInits)
746 ModuleInits.push_back(F);
748 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
757 SmallString<256> InitFnName;
758 llvm::raw_svector_ostream
Out(InitFnName);
760 .mangleModuleInitializer(Primary, Out);
762 FTy, llvm::Twine(InitFnName), FI, SourceLocation(),
false,
763 llvm::GlobalVariable::ExternalLinkage);
768 if (!ModuleInits.empty()) {
770 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
772 llvm::GlobalVariable::InternalLinkage,
773 llvm::ConstantInt::get(
Int8Ty, 0), InitFnName.str() +
"__in_chrg");
776 GuardAddr = ConstantAddress(Guard,
Int8Ty, GuardAlign);
778 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits,
792 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
799 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
801 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
802 Fn->addFnAttr(
"device-init");
806 PrioritizedCXXGlobalInits.clear();
807 CXXGlobalInits.clear();
817 for (
size_t i = 0; i <
FileName.size(); ++i) {
828 assert(Priority <= 65535 &&
"Priority should always be <= 65535.");
832 std::string PrioritySuffix = llvm::utostr(Priority);
833 PrioritySuffix = std::string(6 - PrioritySuffix.size(),
'0') + PrioritySuffix;
835 return PrioritySuffix;
839CodeGenModule::EmitCXXGlobalInitFunc() {
840 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
841 CXXGlobalInits.pop_back();
844 SmallVector<llvm::Function *, 8> ModuleInits;
845 if (CXX20ModuleInits)
848 ImportedModules.getArrayRef())) {
849 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
850 SmallString<256> FnName;
852 llvm::raw_svector_ostream
Out(FnName);
854 .mangleModuleInitializer(M, Out);
857 "We should only have one use of the initializer call");
858 llvm::Function *
Fn = llvm::Function::Create(
859 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
860 ModuleInits.push_back(Fn);
863 if (ModuleInits.empty() && CXXGlobalInits.empty() &&
864 PrioritizedCXXGlobalInits.empty())
867 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
871 if (!PrioritizedCXXGlobalInits.empty()) {
872 SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;
873 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
874 PrioritizedCXXGlobalInits.end());
878 for (SmallVectorImpl<GlobalInitData >::iterator
879 I = PrioritizedCXXGlobalInits.begin(),
880 E = PrioritizedCXXGlobalInits.end(); I != E; ) {
881 SmallVectorImpl<GlobalInitData >::iterator
882 PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
884 LocalCXXGlobalInits.clear();
886 unsigned int Priority = I->first.priority;
891 if (!ModuleInits.empty()) {
892 for (
auto *F : ModuleInits)
893 LocalCXXGlobalInits.push_back(F);
897 for (; I < PrioE; ++I)
898 LocalCXXGlobalInits.push_back(I->second);
900 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, LocalCXXGlobalInits);
903 PrioritizedCXXGlobalInits.clear();
906 if (
getCXXABI().useSinitAndSterm() && ModuleInits.empty() &&
907 CXXGlobalInits.empty())
910 for (
auto *F : CXXGlobalInits)
911 ModuleInits.push_back(F);
912 CXXGlobalInits.clear();
919 if (CXX20ModuleInits &&
getContext().getCurrentNamedModule() &&
920 !
getContext().getCurrentNamedModule()->isModuleImplementation()) {
921 SmallString<256> InitFnName;
922 llvm::raw_svector_ostream
Out(InitFnName);
924 .mangleModuleInitializer(
getContext().getCurrentNamedModule(), Out);
926 FTy, llvm::Twine(InitFnName), FI, SourceLocation(),
false,
927 llvm::GlobalVariable::ExternalLinkage);
934 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits);
947 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
954 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
956 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
957 Fn->addFnAttr(
"device-init");
963void CodeGenModule::EmitCXXGlobalCleanUpFunc() {
964 if (CXXGlobalDtorsOrStermFinalizers.empty() &&
965 PrioritizedCXXStermFinalizers.empty())
968 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
972 if (!PrioritizedCXXStermFinalizers.empty()) {
973 SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> LocalCXXStermFinalizers;
974 llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(),
975 PrioritizedCXXStermFinalizers.end());
979 for (SmallVectorImpl<StermFinalizerData>::iterator
980 I = PrioritizedCXXStermFinalizers.begin(),
981 E = PrioritizedCXXStermFinalizers.end();
983 SmallVectorImpl<StermFinalizerData>::iterator PrioE =
984 std::upper_bound(I + 1, E, *I, StermFinalizerPriorityCmp());
986 LocalCXXStermFinalizers.clear();
988 unsigned int Priority = I->first.priority;
992 for (; I < PrioE; ++I) {
993 llvm::FunctionCallee DtorFn = I->second;
994 LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),
995 DtorFn.getCallee(),
nullptr);
998 CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(
999 Fn, LocalCXXStermFinalizers);
1002 PrioritizedCXXStermFinalizers.clear();
1005 if (CXXGlobalDtorsOrStermFinalizers.empty())
1009 llvm::Function *
Fn =
1012 CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(
1013 Fn, CXXGlobalDtorsOrStermFinalizers);
1015 CXXGlobalDtorsOrStermFinalizers.clear();
1021 llvm::GlobalVariable *
Addr,
1024 if (D->
hasAttr<NoDebugAttr>())
1025 DebugInfo =
nullptr;
1042 if (
Addr->hasWeakLinkage() ||
Addr->hasLinkOnceLinkage() ||
1064 llvm::BasicBlock *ExitBlock =
nullptr;
1068 llvm::Value *GuardVal =
Builder.CreateLoad(Guard);
1069 llvm::Value *Uninit =
Builder.CreateIsNull(GuardVal,
1070 "guard.uninitialized");
1079 Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);
1085 CGM.getDataLayout().getTypeAllocSize(GuardVal->getType())));
1097 for (llvm::Function *
Decl : Decls) {
1102 Scope.ForceCleanup();
1115 ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
1117 DtorsOrStermFinalizers) {
1126 for (
unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) {
1127 llvm::FunctionType *CalleeTy;
1128 llvm::Value *Callee;
1129 llvm::Constant *Arg;
1130 std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];
1135 addConvergenceControlBundle(BundleList);
1137 llvm::CallBase *CI =
nullptr;
1138 if (Arg ==
nullptr) {
1140 CGM.getCXXABI().useSinitAndSterm() &&
1141 "Arg could not be nullptr unless using sinit and sterm functions.");
1142 CI =
Builder.CreateCall(CalleeTy, Callee, {}, BundleList);
1147 assert(Arg->getType()->isPointerTy());
1148 assert(CalleeTy->getParamType(0)->isPointerTy());
1149 unsigned ActualAddrSpace = Arg->getType()->getPointerAddressSpace();
1150 unsigned ExpectedAddrSpace =
1151 CalleeTy->getParamType(0)->getPointerAddressSpace();
1152 if (ActualAddrSpace != ExpectedAddrSpace) {
1153 llvm::PointerType *PTy =
1155 Arg = llvm::ConstantExpr::getAddrSpaceCast(Arg, PTy);
1158 CI =
Builder.CreateCall(CalleeTy, Callee, Arg, BundleList);
1162 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
1163 CI->setCallingConv(F->getCallingConv());
1165 setConvergentCallSite(CI, IsConvergent);
1177 bool useEHCleanupForArray,
const VarDecl *VD) {
1184 llvm::FunctionType *FTy =
CGM.getTypes().GetFunctionType(FI);
1185 llvm::Function *fn =
CGM.CreateGlobalInitOrCleanUpFunction(
1186 FTy,
"__cxx_global_array_dtor", FI, VD->
getLocation());
static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, ConstantAddress DeclPtr)
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.
static std::string getPrioritySuffix(unsigned priority)
Compute the zero-padded priority suffix used to name priority-specific global init functions,...
static SmallString< 128 > getTransformedFileName(mlir::ModuleOp mlirModule)
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.
This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
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)
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
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 Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
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 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.
CGCXXABI & getCXXABI() const
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 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)
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.
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.
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.
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
bool assumeFunctionsAreConvergent() const
virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &)=0
bool isInterfaceOrPartition() const
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...
llvm::SmallVector< Module *, 8 > importedModulesToInitialize(Module *Primary, llvm::ArrayRef< Module * > Imported)
The C++20 named modules whose Itanium initializer function the global init function of a translation ...
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Top level wrappers for InstallAPI frontend operations.
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.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
const FunctionProtoType * T
@ 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_.
U cast(CodeGen::Address addr)
@ 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.