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) {
132 llvm::Constant *InvariantStart = CGF.
CGM.
getIntrinsic(InvStartID, ObjectPtr);
138 llvm::ConstantExpr::getBitCast(Addr, CGF.
Int8PtrTy)};
139 CGF.
Builder.CreateCall(InvariantStart, Args);
143 llvm::Constant *DeclPtr,
165 unsigned ActualAddrSpace = DeclPtr->getType()->getPointerAddressSpace();
166 if (ActualAddrSpace != ExpectedAddrSpace) {
168 llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
169 DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
177 &D, DeclAddr, D.
getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
188 assert(PerformInit &&
"cannot have constant initializer which needs "
189 "destruction for reference");
197 llvm::Constant *dtor,
198 llvm::Constant *addr) {
200 llvm::FunctionType *ty = llvm::FunctionType::get(
CGM.
VoidTy,
false);
203 llvm::raw_svector_ostream Out(FnName);
216 llvm::CallInst *call = CGF.
Builder.CreateCall(dtor, addr);
219 if (llvm::Function *dtorFn =
220 dyn_cast<llvm::Function>(dtor->stripPointerCasts()))
221 call->setCallingConv(dtorFn->getCallingConv());
230 llvm::Constant *dtor,
231 llvm::Constant *addr) {
236 llvm::FunctionType *atexitTy =
237 llvm::FunctionType::get(
IntTy, dtorStub->getType(),
false);
239 llvm::Constant *atexit =
242 if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit))
243 atexitFn->setDoesNotThrow();
249 llvm::GlobalVariable *DeclPtr,
256 "this initialization requires a guard variable, which "
257 "the kernel does not support");
270 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
271 Fn->setSection(Section);
279 Fn->setDoesNotThrow();
282 if (
getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
283 SanitizerKind::KernelAddress))
284 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
285 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread))
286 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
287 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory))
288 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
289 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack))
290 Fn->addFnAttr(llvm::Attribute::SafeStack);
299 void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *D,
300 llvm::GlobalVariable *GV,
301 llvm::Function *InitFunc,
303 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
304 TheModule, InitFunc->getType(),
true,
305 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
306 PtrArray->setSection(ISA->getSection());
310 if (llvm::Comdat *C = GV->getComdat())
311 PtrArray->setComdat(C);
315 CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *D,
316 llvm::GlobalVariable *Addr,
325 (D->
hasAttr<CUDADeviceAttr>() || D->
hasAttr<CUDAConstantAttr>() ||
330 auto I = DelayedCXXInitPosition.find(D);
331 if (
I != DelayedCXXInitPosition.end() &&
I->second == ~0U)
334 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
337 llvm::raw_svector_ostream Out(FnName);
347 auto *ISA = D->
getAttr<InitSegAttr>();
351 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,
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)
576 const std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>>
586 for (
unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
587 llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
588 llvm::CallInst *CI =
Builder.CreateCall(Callee,
589 DtorsAndObjects[e - i - 1].second);
591 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
592 CI->setCallingConv(F->getCallingConv());
604 bool useEHCleanupForArray,
const VarDecl *VD) {
608 args.push_back(&Dst);
614 FTy,
"__cxx_global_array_dtor", FI, VD->
getLocation());
620 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.
Parameter for captured context.
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
void ForceCleanup(std::initializer_list< llvm::Value ** > ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
const LangOptions & getLangOpts() const
void GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, const std::vector< std::pair< llvm::WeakTrackingVH, llvm::Constant * >> &DtorsAndObjects)
GenerateCXXGlobalDtorsFunc - Generates code for destroying global variables.
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.
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::Constant * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false, ForDefinition_t IsForDefinition=NotForDefinition)
Return the address of the constructor/destructor of the given type.
llvm::CallInst * EmitRuntimeCall(llvm::Value *callee, const Twine &name="")
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...
llvm::Constant * CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false)
Create a new runtime function with the specified type and name.
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.
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...
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
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, LValueBaseInfo BaseInfo=LValueBaseInfo(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...
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.
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.
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.
LValue MakeAddrLValue(Address Addr, QualType T, LValueBaseInfo BaseInfo=LValueBaseInfo(AlignmentSource::Type))
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
SourceLocation getLocation() 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...
static CharUnits getDeclAlign(Expr *E, CharUnits TypeAlign, ASTContext &Context)
A helper function to get the alignment of a Decl referred to by DeclRefExpr or MemberExpr.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.