19 #include "llvm/ADT/StringExtras.h"
20 #include "llvm/IR/Intrinsics.h"
21 #include "llvm/Support/Path.h"
23 using namespace clang;
24 using namespace CodeGen;
30 "Should not call EmitDeclInit on a reference!");
58 llvm_unreachable(
"bad evaluation kind");
82 assert(!D.
getTLSKind() &&
"should have rejected this");
86 llvm::Constant *
function;
87 llvm::Constant *argument;
93 bool CanRegisterDestructor =
101 if (Record && (CanRegisterDestructor || UsingExternalHelper)) {
106 argument = llvm::ConstantExpr::getBitCast(
114 argument = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
123 llvm::Constant *Addr) {
136 llvm::ConstantExpr::getBitCast(Addr, CGF.
Int8PtrTy)};
137 CGF.
Builder.CreateCall(InvariantStart, Args);
141 llvm::Constant *DeclPtr,
163 unsigned ActualAddrSpace = DeclPtr->getType()->getPointerAddressSpace();
164 if (ActualAddrSpace != ExpectedAddrSpace) {
166 llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
167 DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
173 if (
getLangOpts().OpenMP && D.hasAttr<OMPThreadPrivateDeclAttr>())
175 &D, DeclAddr, D.getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
186 assert(PerformInit &&
"cannot have constant initializer which needs "
187 "destruction for reference");
195 llvm::Constant *dtor,
196 llvm::Constant *addr) {
198 llvm::FunctionType *ty = llvm::FunctionType::get(
CGM.
VoidTy,
false);
201 llvm::raw_svector_ostream Out(FnName);
214 llvm::CallInst *call = CGF.
Builder.CreateCall(dtor, addr);
217 if (llvm::Function *dtorFn =
218 dyn_cast<llvm::Function>(dtor->stripPointerCasts()))
219 call->setCallingConv(dtorFn->getCallingConv());
228 llvm::Constant *dtor,
229 llvm::Constant *addr) {
234 llvm::FunctionType *atexitTy =
235 llvm::FunctionType::get(
IntTy, dtorStub->getType(),
false);
237 llvm::Constant *atexit =
239 if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit))
240 atexitFn->setDoesNotThrow();
246 llvm::GlobalVariable *DeclPtr,
253 "this initialization requires a guard variable, which "
254 "the kernel does not support");
267 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
268 Fn->setSection(Section);
276 Fn->setDoesNotThrow();
279 if (
getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
280 SanitizerKind::KernelAddress))
281 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
282 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread))
283 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
284 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory))
285 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
286 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack))
287 Fn->addFnAttr(llvm::Attribute::SafeStack);
296 void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *D,
297 llvm::GlobalVariable *GV,
298 llvm::Function *InitFunc,
300 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
301 TheModule, InitFunc->getType(),
true,
302 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
303 PtrArray->setSection(ISA->getSection());
307 if (llvm::Comdat *C = GV->getComdat())
308 PtrArray->setComdat(C);
312 CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *D,
313 llvm::GlobalVariable *Addr,
322 (D->hasAttr<CUDADeviceAttr>() || D->hasAttr<CUDAConstantAttr>() ||
323 D->hasAttr<CUDASharedAttr>()))
327 auto I = DelayedCXXInitPosition.find(D);
328 if (
I != DelayedCXXInitPosition.end() &&
I->second == ~0U)
331 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
334 llvm::raw_svector_ostream Out(FnName);
344 auto *ISA = D->getAttr<InitSegAttr>();
348 llvm::GlobalVariable *COMDATKey =
358 CXXThreadLocalInits.push_back(Fn);
359 CXXThreadLocalInitVars.push_back(D);
360 }
else if (PerformInit && ISA) {
361 EmitPointerToInitFunc(D, Addr, Fn, ISA);
362 }
else if (
auto *IPA = D->getAttr<InitPriorityAttr>()) {
364 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
378 AddGlobalCtor(Fn, 65535, COMDATKey);
379 }
else if (D->hasAttr<SelectAnyAttr>()) {
383 AddGlobalCtor(Fn, 65535, COMDATKey);
385 I = DelayedCXXInitPosition.find(D);
386 if (
I == DelayedCXXInitPosition.end()) {
387 CXXGlobalInits.push_back(Fn);
388 }
else if (
I->second != ~0U) {
389 assert(
I->second < CXXGlobalInits.size() &&
390 CXXGlobalInits[
I->second] ==
nullptr);
391 CXXGlobalInits[
I->second] = Fn;
396 DelayedCXXInitPosition[D] = ~0U;
399 void CodeGenModule::EmitCXXThreadLocalInitFunc() {
401 *
this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
403 CXXThreadLocalInits.clear();
404 CXXThreadLocalInitVars.clear();
405 CXXThreadLocals.clear();
409 CodeGenModule::EmitCXXGlobalInitFunc() {
410 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
411 CXXGlobalInits.pop_back();
413 if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
416 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
420 if (!PrioritizedCXXGlobalInits.empty()) {
422 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
423 PrioritizedCXXGlobalInits.end());
428 I = PrioritizedCXXGlobalInits.begin(),
429 E = PrioritizedCXXGlobalInits.end();
I !=
E; ) {
431 PrioE = std::upper_bound(
I + 1,
E, *
I, GlobalInitPriorityCmp());
433 LocalCXXGlobalInits.clear();
434 unsigned Priority =
I->first.priority;
437 std::string PrioritySuffix = llvm::utostr(Priority);
439 PrioritySuffix = std::string(6-PrioritySuffix.size(),
'0')+PrioritySuffix;
441 FTy,
"_GLOBAL__I_" + PrioritySuffix, FI);
443 for (;
I < PrioE; ++
I)
444 LocalCXXGlobalInits.push_back(
I->second);
447 AddGlobalCtor(Fn, Priority);
449 PrioritizedCXXGlobalInits.clear();
458 FileName = llvm::sys::path::filename(MainFile->getName());
463 for (
size_t i = 0; i < FileName.size(); ++i) {
471 FTy, llvm::Twine(
"_GLOBAL__sub_I_", FileName), FI);
476 CXXGlobalInits.clear();
479 void CodeGenModule::EmitCXXGlobalDtorFunc() {
480 if (CXXGlobalDtors.empty())
483 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
497 llvm::GlobalVariable *Addr,
500 if (D->hasAttr<NoDebugAttr>())
506 getTypes().arrangeNullaryFunction(),
513 if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage()) {
533 llvm::BasicBlock *ExitBlock =
nullptr;
539 "guard.uninitialized");
542 Builder.CreateCondBr(Uninit, InitBlock, ExitBlock);
559 for (
unsigned i = 0, e = Decls.size(); i != e; ++i)
575 const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> >
585 for (
unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
586 llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
587 llvm::CallInst *CI =
Builder.CreateCall(Callee,
588 DtorsAndObjects[e - i - 1].second);
590 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
591 CI->setCallingConv(F->getCallingConv());
603 bool useEHCleanupForArray,
const VarDecl *VD) {
607 args.push_back(&dst);
613 FTy,
"__cxx_global_array_dtor", FI, VD->getLocation());
619 emitDestroy(addr, type, destroyer, useEHCleanupForArray);
const CGFunctionInfo & arrangeBuiltinFunctionDeclaration(QualType resultType, const FunctionArgList &args)
A builtin function is a freestanding function using the default C conventions.
llvm::IntegerType * IntTy
int
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, Address Guard=Address::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
A (possibly-)qualified type.
CodeGenTypes & getTypes()
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
llvm::Module & getModule() const
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
llvm::CallingConv::ID getRuntimeCC() const
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
const Expr * getInit() const
const LangOptions & getLangOpts() const
VarDecl - An instance of this class is created to represent a variable declaration or definition...
TLSKind getTLSKind() const
llvm::Value * EmitObjCAutoreleasePoolPush()
Produce the code to do a objc_autoreleasepool_push.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
virtual bool canCallMismatchedFunctionType() const
Returns true if the target allows calling a function through a pointer with a different signature tha...
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
llvm::Constant * getPointer() const
static 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_.
static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, ConstantAddress addr)
Emit code to cause the destruction of the given variable with static storage duration.
void emitDestroy(Address addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
emitDestroy - Immediately perform the destruction of the given object.
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
llvm::IntegerType * Int64Ty
RValue EmitReferenceBindingToExpr(const Expr *E)
Emits a reference binding to the passed in expression.
bool isReferenceType() const
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
void GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, const std::vector< std::pair< llvm::WeakVH, llvm::Constant * > > &DtorsAndObjects)
GenerateCXXGlobalDtorsFunc - Generates code for destroying 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.
static ApplyDebugLocation CreateArtificial(CodeGenFunction &CGF)
Apply TemporaryLocation if it is valid.
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::PointerType * VoidPtrTy
bool needsEHCleanup(QualType::DestructionKind kind)
Determines whether an EH cleanup is required to destroy a type with the given destruction kind...
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, llvm::Constant *addr)
Call atexit() with a function that passes the given argument to the given function.
Scope - A scope is a transient data structure that is used while parsing the program.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
detail::InMemoryDirectory::const_iterator I
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...
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest, bool threadlocal=false)=0
bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor)
isTypeConstant - Determine whether an object of this type can be emitted as a constant.
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource AlignSource=AlignmentSource::Type)
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
const TargetInfo & getTarget() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated...
virtual void mangleDynamicAtExitDestructor(const VarDecl *D, raw_ostream &)=0
void EmitCXXGuardedInit(const VarDecl &D, llvm::GlobalVariable *DeclPtr, bool PerformInit)
Emit code in this function to perform a guarded variable initialization.
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
static TypeEvaluationKind getEvaluationKind(QualType T)
hasAggregateLLVMType - Return true if the specified AST type will map into an aggregate LLVM type or ...
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...
Expr - This represents one expression.
CGCXXABI & getCXXABI() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource AlignSource=AlignmentSource::Type, llvm::MDNode *TBAAInfo=nullptr, bool isInit=false, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
void SetInternalFunctionAttributes(const Decl *D, llvm::Function *F, const CGFunctionInfo &FI)
Set the attributes on the LLVM function for the given decl and function info.
Represents a C++ destructor within a class.
virtual void mangleDynamicInitializer(const VarDecl *D, raw_ostream &)=0
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 ...
ASTContext & getContext() const
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::Constant *Dtor, llvm::Constant *Addr)=0
Emit code to force the execution of a destructor during global teardown.
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...
bool isExternallyVisible() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=None)
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
GlobalDecl - represents a global declaration.
The l-value was considered opaque, so the alignment was determined from a type.
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeSet ExtraAttrs=llvm::AttributeSet())
Create a new runtime function with the specified type and name.
ASTContext & getContext() const
Encodes a location in the source.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > PL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
Create a stub function, suitable for being passed to atexit, which passes the given address to the gi...
Cached information about one file (either on disk or in the virtual file system). ...
const CodeGenOptions & getCodeGenOpts() const
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.
const LangOptions & getLangOpts() const
MangleContext & getMangleContext()
Gets the mangle context.
FileID getMainFileID() const
Returns the FileID of the main source file.
llvm::Constant * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, bool IsForDefinition=false)
Return the address of the constructor/destructor of the given type.
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
void FinishFunction(SourceLocation EndLoc=SourceLocation())
FinishFunction - Complete IR generation of the current function.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
CGFunctionInfo - Class to encapsulate the information about a function definition.
This class organizes the cross-function state that is used while generating LLVM code.
CGOpenMPRuntime & getOpenMPRuntime()
Return a reference to the configured OpenMP runtime.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
SourceLocation getLocStart() const LLVM_READONLY
detail::InMemoryDirectory::const_iterator E
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
bool isInSanitizerBlacklist(llvm::Function *Fn, SourceLocation Loc) const
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type. ...
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, Address dest)=0
llvm::PointerType * Int8PtrTy
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, ConstantAddress DeclPtr)
SourceManager & getSourceManager()
Represents a C++ struct/union/class.
bool isObjCStrong() const
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, SourceLocation Loc=SourceLocation(), bool TLS=false)
A specialization of Address that requires the address to be an LLVM Constant.
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)
unsigned getTargetAddressSpace(QualType T) const
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
CodeGenTypes & getTypes() const
LValue - This represents an lvalue references.
This class handles loading and caching of source files into memory.
bool supportsCOMDAT() const
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...
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.