19 #include "llvm/ADT/StringExtras.h" 20 #include "llvm/IR/Intrinsics.h" 21 #include "llvm/IR/MDBuilder.h" 22 #include "llvm/Support/Path.h" 24 using namespace clang;
25 using namespace CodeGen;
31 "Should not call EmitDeclInit on a reference!");
59 llvm_unreachable(
"bad evaluation kind");
83 assert(!D.
getTLSKind() &&
"should have rejected this");
87 llvm::Constant *
function;
88 llvm::Constant *argument;
94 bool CanRegisterDestructor =
102 if (Record && (CanRegisterDestructor || UsingExternalHelper)) {
107 argument = llvm::ConstantExpr::getBitCast(
115 argument = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
124 llvm::Constant *Addr) {
133 llvm::Constant *InvariantStart = CGF.
CGM.
getIntrinsic(InvStartID, ObjectPtr);
139 llvm::ConstantExpr::getBitCast(Addr, CGF.
Int8PtrTy)};
140 CGF.
Builder.CreateCall(InvariantStart, Args);
144 llvm::Constant *DeclPtr,
166 unsigned ActualAddrSpace = DeclPtr->getType()->getPointerAddressSpace();
167 if (ActualAddrSpace != ExpectedAddrSpace) {
169 llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
170 DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
177 D.
hasAttr<OMPThreadPrivateDeclAttr>()) {
179 &D, DeclAddr, D.
getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
191 assert(PerformInit &&
"cannot have constant initializer which needs " 192 "destruction for reference");
200 llvm::Constant *dtor,
201 llvm::Constant *addr) {
203 llvm::FunctionType *ty = llvm::FunctionType::get(
CGM.
VoidTy,
false);
206 llvm::raw_svector_ostream Out(FnName);
219 llvm::CallInst *call = CGF.
Builder.CreateCall(dtor, addr);
222 if (llvm::Function *dtorFn =
223 dyn_cast<llvm::Function>(dtor->stripPointerCasts()))
224 call->setCallingConv(dtorFn->getCallingConv());
233 llvm::Constant *dtor,
234 llvm::Constant *addr) {
239 llvm::FunctionType *atexitTy =
240 llvm::FunctionType::get(
IntTy, dtorStub->getType(),
false);
242 llvm::Constant *atexit =
245 if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit))
246 atexitFn->setDoesNotThrow();
252 llvm::GlobalVariable *DeclPtr,
259 "this initialization requires a guard variable, which " 260 "the kernel does not support");
266 llvm::BasicBlock *InitBlock,
267 llvm::BasicBlock *NoInitBlock,
274 static const uint64_t InitsPerTLSVar = 1024;
275 static const uint64_t InitsPerLocalVar = 1024 * 1024;
277 llvm::MDNode *Weights;
289 NumInits = InitsPerTLSVar;
291 NumInits = InitsPerLocalVar;
296 Weights = MDHelper.createBranchWeights(1, NumInits - 1);
299 Builder.CreateCondBr(NeedsInit, InitBlock, NoInitBlock, Weights);
303 llvm::FunctionType *FTy,
const Twine &Name,
const CGFunctionInfo &FI,
310 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
311 Fn->setSection(Section);
314 SetInternalFunctionAttributes(
nullptr, Fn, FI);
319 Fn->setDoesNotThrow();
321 if (
getLangOpts().Sanitize.has(SanitizerKind::Address) &&
322 !isInSanitizerBlacklist(SanitizerKind::Address, Fn, Loc))
323 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
325 if (
getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&
326 !isInSanitizerBlacklist(SanitizerKind::KernelAddress, Fn, Loc))
327 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
329 if (
getLangOpts().Sanitize.has(SanitizerKind::HWAddress) &&
330 !isInSanitizerBlacklist(SanitizerKind::HWAddress, Fn, Loc))
331 Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
333 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
334 !isInSanitizerBlacklist(SanitizerKind::Thread, Fn, Loc))
335 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
337 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
338 !isInSanitizerBlacklist(SanitizerKind::Memory, Fn, Loc))
339 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
341 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
342 !isInSanitizerBlacklist(SanitizerKind::SafeStack, Fn, Loc))
343 Fn->addFnAttr(llvm::Attribute::SafeStack);
351 void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *D,
352 llvm::GlobalVariable *GV,
353 llvm::Function *InitFunc,
355 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
356 TheModule, InitFunc->getType(),
true,
357 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
358 PtrArray->setSection(ISA->getSection());
359 addUsedGlobal(PtrArray);
362 if (llvm::Comdat *C = GV->getComdat())
363 PtrArray->setComdat(C);
367 CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *D,
368 llvm::GlobalVariable *Addr,
377 (D->
hasAttr<CUDADeviceAttr>() || D->
hasAttr<CUDAConstantAttr>() ||
382 auto I = DelayedCXXInitPosition.find(D);
383 if (I != DelayedCXXInitPosition.end() && I->second == ~0U)
386 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
389 llvm::raw_svector_ostream Out(FnName);
390 getCXXABI().getMangleContext().mangleDynamicInitializer(D, Out);
395 CreateGlobalInitOrDestructFunction(FTy, FnName.str(),
399 auto *ISA = D->
getAttr<InitSegAttr>();
403 llvm::GlobalVariable *COMDATKey =
410 CXXThreadLocalInits.push_back(Fn);
411 CXXThreadLocalInitVars.push_back(D);
412 }
else if (PerformInit && ISA) {
413 EmitPointerToInitFunc(D, Addr, Fn, ISA);
414 }
else if (
auto *IPA = D->
getAttr<InitPriorityAttr>()) {
416 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
430 AddGlobalCtor(Fn, 65535, COMDATKey);
431 }
else if (D->
hasAttr<SelectAnyAttr>()) {
435 AddGlobalCtor(Fn, 65535, COMDATKey);
437 I = DelayedCXXInitPosition.find(D);
438 if (I == DelayedCXXInitPosition.end()) {
439 CXXGlobalInits.push_back(Fn);
440 }
else if (I->second != ~0U) {
441 assert(I->second < CXXGlobalInits.size() &&
442 CXXGlobalInits[I->second] ==
nullptr);
443 CXXGlobalInits[I->second] = Fn;
448 DelayedCXXInitPosition[D] = ~0U;
451 void CodeGenModule::EmitCXXThreadLocalInitFunc() {
452 getCXXABI().EmitThreadLocalInitFuncs(
453 *
this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
455 CXXThreadLocalInits.clear();
456 CXXThreadLocalInitVars.clear();
457 CXXThreadLocals.clear();
461 CodeGenModule::EmitCXXGlobalInitFunc() {
462 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
463 CXXGlobalInits.pop_back();
465 if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
468 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
472 if (!PrioritizedCXXGlobalInits.empty()) {
474 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
475 PrioritizedCXXGlobalInits.end());
480 I = PrioritizedCXXGlobalInits.begin(),
481 E = PrioritizedCXXGlobalInits.end(); I != E; ) {
483 PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
485 LocalCXXGlobalInits.clear();
486 unsigned Priority = I->first.priority;
489 std::string PrioritySuffix = llvm::utostr(Priority);
491 PrioritySuffix = std::string(6-PrioritySuffix.size(),
'0')+PrioritySuffix;
492 llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
493 FTy,
"_GLOBAL__I_" + PrioritySuffix, FI);
495 for (; I < PrioE; ++I)
496 LocalCXXGlobalInits.push_back(I->second);
499 AddGlobalCtor(Fn, Priority);
501 PrioritizedCXXGlobalInits.clear();
507 SmallString<128> FileName = llvm::sys::path::filename(getModule().getName());
508 if (FileName.empty())
511 for (
size_t i = 0; i < FileName.size(); ++i) {
518 llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
519 FTy, llvm::Twine(
"_GLOBAL__sub_I_", FileName), FI);
524 CXXGlobalInits.clear();
527 void CodeGenModule::EmitCXXGlobalDtorFunc() {
528 if (CXXGlobalDtors.empty())
531 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
536 CreateGlobalInitOrDestructFunction(FTy,
"_GLOBAL__D_a", FI);
545 llvm::GlobalVariable *Addr,
554 getTypes().arrangeNullaryFunction(),
561 if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage()) {
581 llvm::BasicBlock *ExitBlock =
nullptr;
587 "guard.uninitialized");
608 for (
unsigned i = 0, e = Decls.size(); i != e; ++i)
625 const std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>>
635 for (
unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
636 llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
637 llvm::CallInst *CI =
Builder.CreateCall(Callee,
638 DtorsAndObjects[e - i - 1].second);
640 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
641 CI->setCallingConv(F->getCallingConv());
653 bool useEHCleanupForArray,
const VarDecl *VD) {
657 args.push_back(&Dst);
663 FTy,
"__cxx_global_array_dtor", FI, VD->
getLocation());
669 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.
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.
llvm::IntegerType * IntTy
int
Other implicit parameter.
Destroyer * getDestroyer(QualType::DestructionKind destructionKind)
A (possibly-)qualified type.
CodeGenTypes & getTypes()
const CodeGenOptions & getCodeGenOpts() const
llvm::LLVMContext & getLLVMContext()
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function *> CXXThreadLocals, Address Guard=Address::invalid())
GenerateCXXGlobalInitFunc - Generates code for initializing global variables.
void EmitComplexExprIntoLValue(const Expr *E, LValue dest, bool isInit)
EmitComplexExprIntoLValue - Emit the given expression of complex type and place its result into the s...
VarDecl - An instance of this class is created to represent a variable declaration or definition...
llvm::Value * EmitObjCAutoreleasePoolPush()
Produce the code to do a objc_autoreleasepool_push.
llvm::Type * ConvertTypeForMem(QualType T)
ConvertTypeForMem - Convert type T into a llvm::Type.
static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, ConstantAddress addr)
Emit code to cause the destruction of the given variable with static storage duration.
const TargetInfo & getTarget() const
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.
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="")
bool isReferenceType() const
void GenerateCXXGlobalVarDeclInitFunc(llvm::Function *Fn, const VarDecl *D, llvm::GlobalVariable *Addr, bool PerformInit)
Emit the code necessary to initialize the given global variable.
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...
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
TemplateSpecializationKind getTemplateSpecializationKind() const
If this variable is an instantiation of a variable template or a static data member of a class templa...
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.
void ForceCleanup(std::initializer_list< llvm::Value **> ValuesToReload={})
Force the emission of cleanups now, instead of waiting until this object is destroyed.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
virtual bool canCallMismatchedFunctionType() const
Returns true if the target allows calling a function through a pointer with a different signature tha...
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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
ASTContext & getContext() const
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
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
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
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...
llvm::CallingConv::ID getRuntimeCC() const
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)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
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.
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
const FunctionProtoType * T
const CGFunctionInfo & arrangeNullaryFunction()
A nullary function is a freestanding function of type 'void ()'.
Represents a C++ destructor within a class.
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 ...
TLSKind getTLSKind() 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.
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
EmitCXXGlobalVarDeclInit - Create the initializer for a C++ variable with global storage.
bool isObjCStrong() const
ASTContext & getContext() const
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.
Encodes a location in the source.
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...
bool hasGlobalStorage() const
Returns true for all variables that do not have local 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.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after...
MangleContext & getMangleContext()
Gets the mangle context.
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.
FunctionArgList - Type for representing both the decl and type of parameters to a function...
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
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.
Dataflow Directional Tag Classes.
const Expr * getInit() const
llvm::Constant * getPointer() const
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
SourceLocation getLocStart() const LLVM_READONLY
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type *> Tys=None)
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
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
CodeGenTypes & getTypes() const
llvm::PointerType * Int8PtrTy
void EmitScalarInit(const Expr *init, const ValueDecl *D, LValue lvalue, bool capturedByInit)
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)
Represents a C++ struct/union/class.
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.
CGCXXABI & getCXXABI() const
void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)
void GenerateCXXGlobalDtorsFunc(llvm::Function *Fn, const std::vector< std::pair< llvm::WeakTrackingVH, llvm::Constant *>> &DtorsAndObjects)
GenerateCXXGlobalDtorsFunc - Generates code for destroying global variables.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
Set the IRBuilder to not attach debug locations.
bool isLocalVarDecl() const
isLocalVarDecl - Returns true for local variable declarations other than parameters.
LValue - This represents an lvalue references.
const LangOptions & getLangOpts() const
unsigned getTargetAddressSpace(QualType T) const
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_.
SourceLocation getLocation() const
bool isExternallyVisible() 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 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.
void Destroyer(CodeGenFunction &CGF, Address addr, QualType ty)
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.