22#include "llvm/ADT/StringExtras.h"
23#include "llvm/IR/Intrinsics.h"
24#include "llvm/IR/MDBuilder.h"
25#include "llvm/Support/Path.h"
35 "VarDecl must have global or local (in the case of OpenCL) storage!");
37 "Should not call EmitDeclInit on a reference!");
46 if (lv.isObjCStrong())
49 else if (lv.isObjCWeak())
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(
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) {
160 if (!
CGM.getCodeGenOpts().OptimizationLevel)
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));
210 if (!T->isReferenceType()) {
212 D.
hasAttr<OMPThreadPrivateDeclAttr>()) {
213 (void)
CGM.getOpenMPRuntime().emitThreadPrivateVarDefinition(
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);
244 CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&VD, Out);
248 llvm::Function *fn =
CGM.CreateGlobalInitOrCleanUpFunction(
251 CodeGenFunction CGF(
CGM);
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());
273 return CGM.getFunctionPointer(fn, fnType);
279 const VarDecl &D, llvm::FunctionCallee Dtor, llvm::Constant *
Addr,
280 llvm::FunctionCallee &
AtExit) {
283 llvm::raw_svector_ostream Out(FnName);
284 CGM.getCXXABI().getMangleContext().mangleDynamicAtExitDestructor(&D, Out);
292 llvm::FunctionType *StubTy =
293 llvm::FunctionType::get(
CGM.IntTy, {CGM.IntTy},
true);
295 llvm::Function *DtorStub =
CGM.CreateGlobalInitOrCleanUpFunction(
298 CodeGenFunction CGF(
CGM);
311 llvm::CallInst *call = CGF.
Builder.CreateCall(Dtor,
Addr);
314 if (
auto *DtorFn = dyn_cast<llvm::Function>(
315 Dtor.getCallee()->stripPointerCastsAndAliases()))
316 call->setCallingConv(DtorFn->getCallingConv());
329 llvm::FunctionCallee dtor,
330 llvm::Constant *addr) {
338 llvm::FunctionCallee Dtor,
339 llvm::Constant *
Addr) {
341 llvm::Function *dtorStub =
343 CGM.AddGlobalDtor(dtorStub);
348 assert(dtorStub->getType()->isPointerTy() &&
349 "Argument to atexit has a wrong type.");
351 llvm::FunctionType *atexitTy =
352 llvm::FunctionType::get(
IntTy, dtorStub->getType(),
false);
354 llvm::FunctionCallee atexit =
355 CGM.CreateRuntimeFunction(atexitTy,
"atexit", llvm::AttributeList(),
357 if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit.getCallee()))
358 atexitFn->setDoesNotThrow();
372 assert(dtorStub->getType()->isPointerTy() &&
373 "Argument to unatexit has a wrong type.");
375 llvm::FunctionType *unatexitTy =
376 llvm::FunctionType::get(
IntTy, {dtorStub->getType()},
false);
378 llvm::FunctionCallee unatexit =
379 CGM.CreateRuntimeFunction(unatexitTy,
"unatexit", llvm::AttributeList());
387 llvm::GlobalVariable *DeclPtr,
392 if (
CGM.getCodeGenOpts().ForbidGuardVariables)
394 "this initialization requires a guard variable, which "
395 "the kernel does not support");
397 CGM.getCXXABI().EmitGuardedInit(*
this, D, DeclPtr, PerformInit);
401 llvm::BasicBlock *InitBlock,
402 llvm::BasicBlock *NoInitBlock,
409 static const uint64_t InitsPerTLSVar = 1024;
410 static const uint64_t InitsPerLocalVar = 1024 * 1024;
412 llvm::MDNode *Weights;
424 NumInits = InitsPerTLSVar;
426 NumInits = InitsPerLocalVar;
430 llvm::MDBuilder MDHelper(
CGM.getLLVMContext());
431 Weights = MDHelper.createBranchWeights(1, NumInits - 1);
434 Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);
438 llvm::FunctionType *FTy,
const Twine &Name,
const CGFunctionInfo &FI,
440 llvm::Function *Fn = llvm::Function::Create(FTy,
Linkage, Name, &
getModule());
444 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
445 Fn->setSection(Section);
448 if (
Linkage == llvm::GlobalVariable::InternalLinkage)
459 Fn->setDoesNotThrow();
461 if (
getLangOpts().Sanitize.has(SanitizerKind::Address) &&
463 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
465 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&
467 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
469 if (
getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&
471 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
473 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelHWAddress) &&
475 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
477 if (
getLangOpts().Sanitize.has(SanitizerKind::MemtagStack) &&
479 Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
481 if (
getLangOpts().Sanitize.has(SanitizerKind::Type) &&
483 Fn->addFnAttr(llvm::Attribute::SanitizeType);
485 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
487 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
489 if (
getLangOpts().Sanitize.has(SanitizerKind::NumericalStability) &&
491 Fn->addFnAttr(llvm::Attribute::SanitizeNumericalStability);
493 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
495 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
497 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelMemory) &&
499 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
501 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
503 Fn->addFnAttr(llvm::Attribute::SafeStack);
505 if (
getLangOpts().Sanitize.has(SanitizerKind::ShadowCallStack) &&
507 Fn->addFnAttr(llvm::Attribute::ShadowCallStack);
515void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *D,
516 llvm::GlobalVariable *GV,
517 llvm::Function *InitFunc,
519 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
520 TheModule, InitFunc->getType(),
true,
521 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
522 PtrArray->setSection(ISA->getSection());
526 if (llvm::Comdat *
C = GV->getComdat())
527 PtrArray->setComdat(
C);
531CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *D,
532 llvm::GlobalVariable *
Addr,
541 (D->
hasAttr<CUDADeviceAttr>() || D->
hasAttr<CUDAConstantAttr>() ||
546 auto I = DelayedCXXInitPosition.find(D);
547 if (I != DelayedCXXInitPosition.end() && I->second == ~0
U)
550 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
553 llvm::raw_svector_ostream Out(FnName);
561 auto *ISA = D->
getAttr<InitSegAttr>();
565 llvm::GlobalVariable *COMDATKey =
572 CXXThreadLocalInits.push_back(Fn);
573 CXXThreadLocalInitVars.push_back(D);
574 }
else if (PerformInit && ISA) {
578 if (ISA->getSection() ==
".CRT$XCC")
580 else if (ISA->getSection() ==
".CRT$XCL")
586 EmitPointerToInitFunc(D,
Addr, Fn, ISA);
587 }
else if (
auto *IPA = D->
getAttr<InitPriorityAttr>()) {
588 OrderGlobalInitsOrStermFinalizers Key(IPA->getPriority(),
589 PrioritizedCXXGlobalInits.size());
590 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
635 I = DelayedCXXInitPosition.find(D);
637 I == DelayedCXXInitPosition.end() ? CXXGlobalInits.size() : I->second;
639 if (COMDATKey && (
getTriple().isOSBinFormatELF() ||
649 llvm::Comdat *
C =
Addr->getComdat();
650 if (COMDATKey &&
C &&
656 I = DelayedCXXInitPosition.find(D);
657 if (I == DelayedCXXInitPosition.end()) {
658 CXXGlobalInits.push_back(Fn);
659 }
else if (I->second != ~0U) {
660 assert(I->second < CXXGlobalInits.size() &&
661 CXXGlobalInits[I->second] ==
nullptr);
662 CXXGlobalInits[I->second] =
Fn;
667 DelayedCXXInitPosition[D] = ~0U;
670void CodeGenModule::EmitCXXThreadLocalInitFunc() {
672 *
this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
674 CXXThreadLocalInits.clear();
675 CXXThreadLocalInitVars.clear();
676 CXXThreadLocals.clear();
694void CodeGenModule::EmitCXXModuleInitFunc(
Module *Primary) {
696 "The function should only be called for C++20 named module interface"
699 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
700 CXXGlobalInits.pop_back();
706 llvm::SmallSetVector<Module *, 8> AllImports;
708 for (
auto I : Primary->
Exports)
709 AllImports.insert(I.first);
711 AllImports.insert_range(Primary->
Imports);
715 assert((SubM->isGlobalModule() || SubM->isPrivateModule()) &&
716 "The sub modules of C++20 module unit should only be global module "
717 "fragments or private module framents.");
718 assert(SubM->Exports.empty() &&
719 "The global mdoule fragments and the private module fragments are "
720 "not allowed to export import modules.");
721 AllImports.insert_range(SubM->Imports);
724 SmallVector<llvm::Function *, 8> ModuleInits;
725 for (
Module *M : AllImports) {
727 if (M->isHeaderLikeModule())
731 if (!M->isNamedModuleInterfaceHasInit())
733 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
734 SmallString<256> FnName;
736 llvm::raw_svector_ostream
Out(FnName);
738 .mangleModuleInitializer(M, Out);
741 "We should only have one use of the initializer call");
742 llvm::Function *
Fn = llvm::Function::Create(
743 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
744 ModuleInits.push_back(Fn);
749 if (!PrioritizedCXXGlobalInits.empty()) {
750 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
751 PrioritizedCXXGlobalInits.end());
752 for (SmallVectorImpl<GlobalInitData>::iterator
753 I = PrioritizedCXXGlobalInits.begin(),
754 E = PrioritizedCXXGlobalInits.end();
756 SmallVectorImpl<GlobalInitData>::iterator PrioE =
757 std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
759 for (; I < PrioE; ++I)
760 ModuleInits.push_back(I->second);
765 for (
auto *F : CXXGlobalInits)
766 ModuleInits.push_back(F);
768 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
777 SmallString<256> InitFnName;
778 llvm::raw_svector_ostream
Out(InitFnName);
780 .mangleModuleInitializer(Primary, Out);
782 FTy, llvm::Twine(InitFnName), FI, SourceLocation(),
false,
783 llvm::GlobalVariable::ExternalLinkage);
788 if (!ModuleInits.empty()) {
790 llvm::GlobalVariable *Guard =
new llvm::GlobalVariable(
792 llvm::GlobalVariable::InternalLinkage,
793 llvm::ConstantInt::get(
Int8Ty, 0), InitFnName.str() +
"__in_chrg");
796 GuardAddr = ConstantAddress(Guard,
Int8Ty, GuardAlign);
798 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits,
812 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
819 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
821 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
822 Fn->addFnAttr(
"device-init");
827 PrioritizedCXXGlobalInits.clear();
828 CXXGlobalInits.clear();
838 for (
size_t i = 0; i <
FileName.size(); ++i) {
849 assert(Priority <= 65535 &&
"Priority should always be <= 65535.");
853 std::string PrioritySuffix = llvm::utostr(Priority);
854 PrioritySuffix = std::string(6 - PrioritySuffix.size(),
'0') + PrioritySuffix;
856 return PrioritySuffix;
860CodeGenModule::EmitCXXGlobalInitFunc() {
861 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
862 CXXGlobalInits.pop_back();
865 SmallVector<llvm::Function *, 8> ModuleInits;
866 if (CXX20ModuleInits)
867 for (
Module *M : ImportedModules) {
869 if (M->isHeaderLikeModule())
873 if (!M->isNamedModuleInterfaceHasInit())
875 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
876 SmallString<256> FnName;
878 llvm::raw_svector_ostream
Out(FnName);
880 .mangleModuleInitializer(M, Out);
883 "We should only have one use of the initializer call");
884 llvm::Function *
Fn = llvm::Function::Create(
885 FTy, llvm::Function::ExternalLinkage, FnName.str(), &
getModule());
886 ModuleInits.push_back(Fn);
889 if (ModuleInits.empty() && CXXGlobalInits.empty() &&
890 PrioritizedCXXGlobalInits.empty())
893 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
897 if (!PrioritizedCXXGlobalInits.empty()) {
898 SmallVector<llvm::Function *, 8> LocalCXXGlobalInits;
899 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
900 PrioritizedCXXGlobalInits.end());
904 for (SmallVectorImpl<GlobalInitData >::iterator
905 I = PrioritizedCXXGlobalInits.begin(),
906 E = PrioritizedCXXGlobalInits.end(); I != E; ) {
907 SmallVectorImpl<GlobalInitData >::iterator
908 PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
910 LocalCXXGlobalInits.clear();
912 unsigned int Priority = I->first.priority;
917 if (!ModuleInits.empty()) {
918 for (
auto *F : ModuleInits)
919 LocalCXXGlobalInits.push_back(F);
923 for (; I < PrioE; ++I)
924 LocalCXXGlobalInits.push_back(I->second);
926 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, LocalCXXGlobalInits);
929 PrioritizedCXXGlobalInits.clear();
932 if (
getCXXABI().useSinitAndSterm() && ModuleInits.empty() &&
933 CXXGlobalInits.empty())
936 for (
auto *F : CXXGlobalInits)
937 ModuleInits.push_back(F);
938 CXXGlobalInits.clear();
945 if (CXX20ModuleInits &&
getContext().getCurrentNamedModule() &&
946 !
getContext().getCurrentNamedModule()->isModuleImplementation()) {
947 SmallString<256> InitFnName;
948 llvm::raw_svector_ostream
Out(InitFnName);
950 .mangleModuleInitializer(
getContext().getCurrentNamedModule(), Out);
952 FTy, llvm::Twine(InitFnName), FI, SourceLocation(),
false,
953 llvm::GlobalVariable::ExternalLinkage);
960 CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, ModuleInits);
973 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
980 Fn->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
982 Fn->setCallingConv(llvm::CallingConv::AMDGPU_KERNEL);
983 Fn->addFnAttr(
"device-init");
989void CodeGenModule::EmitCXXGlobalCleanUpFunc() {
990 if (CXXGlobalDtorsOrStermFinalizers.empty() &&
991 PrioritizedCXXStermFinalizers.empty())
994 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
998 if (!PrioritizedCXXStermFinalizers.empty()) {
999 SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> LocalCXXStermFinalizers;
1000 llvm::array_pod_sort(PrioritizedCXXStermFinalizers.begin(),
1001 PrioritizedCXXStermFinalizers.end());
1005 for (SmallVectorImpl<StermFinalizerData>::iterator
1006 I = PrioritizedCXXStermFinalizers.begin(),
1007 E = PrioritizedCXXStermFinalizers.end();
1009 SmallVectorImpl<StermFinalizerData>::iterator PrioE =
1010 std::upper_bound(I + 1, E, *I, StermFinalizerPriorityCmp());
1012 LocalCXXStermFinalizers.clear();
1014 unsigned int Priority = I->first.priority;
1018 for (; I < PrioE; ++I) {
1019 llvm::FunctionCallee DtorFn = I->second;
1020 LocalCXXStermFinalizers.emplace_back(DtorFn.getFunctionType(),
1021 DtorFn.getCallee(),
nullptr);
1024 CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(
1025 Fn, LocalCXXStermFinalizers);
1028 PrioritizedCXXStermFinalizers.clear();
1031 if (CXXGlobalDtorsOrStermFinalizers.empty())
1035 llvm::Function *
Fn =
1038 CodeGenFunction(*this).GenerateCXXGlobalCleanUpFunc(
1039 Fn, CXXGlobalDtorsOrStermFinalizers);
1041 CXXGlobalDtorsOrStermFinalizers.clear();
1047 llvm::GlobalVariable *
Addr,
1050 if (D->
hasAttr<NoDebugAttr>())
1051 DebugInfo =
nullptr;
1068 if (
Addr->hasWeakLinkage() ||
Addr->hasLinkOnceLinkage() ||
1090 llvm::BasicBlock *ExitBlock =
nullptr;
1094 llvm::Value *GuardVal =
Builder.CreateLoad(Guard);
1095 llvm::Value *Uninit =
Builder.CreateIsNull(GuardVal,
1096 "guard.uninitialized");
1105 Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);
1111 CGM.getDataLayout().getTypeAllocSize(GuardVal->getType())));
1123 for (llvm::Function *
Decl : Decls)
1127 Scope.ForceCleanup();
1140 ArrayRef<std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
1142 DtorsOrStermFinalizers) {
1151 for (
unsigned i = 0, e = DtorsOrStermFinalizers.size(); i != e; ++i) {
1152 llvm::FunctionType *CalleeTy;
1153 llvm::Value *Callee;
1154 llvm::Constant *Arg;
1155 std::tie(CalleeTy, Callee, Arg) = DtorsOrStermFinalizers[e - i - 1];
1157 llvm::CallBase *CI =
nullptr;
1158 if (Arg ==
nullptr) {
1160 CGM.getCXXABI().useSinitAndSterm() &&
1161 "Arg could not be nullptr unless using sinit and sterm functions.");
1162 CI =
Builder.CreateCall(CalleeTy, Callee);
1167 assert(Arg->getType()->isPointerTy());
1168 assert(CalleeTy->getParamType(0)->isPointerTy());
1169 unsigned ActualAddrSpace = Arg->getType()->getPointerAddressSpace();
1170 unsigned ExpectedAddrSpace =
1171 CalleeTy->getParamType(0)->getPointerAddressSpace();
1172 if (ActualAddrSpace != ExpectedAddrSpace) {
1173 llvm::PointerType *PTy =
1175 Arg = llvm::ConstantExpr::getAddrSpaceCast(Arg, PTy);
1177 CI =
Builder.CreateCall(CalleeTy, Callee, Arg);
1181 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
1182 CI->setCallingConv(F->getCallingConv());
1184 if (
CGM.shouldEmitConvergenceTokens() && CI->isConvergent())
1185 CI = addConvergenceControlToken(CI);
1197 bool useEHCleanupForArray,
const VarDecl *VD) {
1204 llvm::FunctionType *FTy =
CGM.getTypes().GetFunctionType(FI);
1205 llvm::Function *fn =
CGM.CreateGlobalInitOrCleanUpFunction(
1206 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 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 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.
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)
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.
virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &)=0
SmallVector< ExportDecl, 2 > Exports
The set of export declarations.
bool isInterfaceOrPartition() const
llvm::iterator_range< submodule_iterator > submodules()
llvm::SmallVector< ModuleRef, 2 > Imports
The set of modules imported by this module, and on which this module depends.
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...
@ 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.
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.
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ 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.