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;
98 argument = llvm::ConstantExpr::getBitCast(
106 argument = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
115 llvm::Constant *Addr) {
128 llvm::ConstantExpr::getBitCast(Addr, CGF.
Int8PtrTy)};
129 CGF.
Builder.CreateCall(InvariantStart, Args);
133 llvm::Constant *DeclPtr,
155 unsigned ActualAddrSpace = DeclPtr->getType()->getPointerAddressSpace();
156 if (ActualAddrSpace != ExpectedAddrSpace) {
158 llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
159 DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
167 &D, DeclAddr, D.
getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
178 assert(PerformInit &&
"cannot have constant initializer which needs "
179 "destruction for reference");
187 llvm::Constant *dtor,
188 llvm::Constant *addr) {
190 llvm::FunctionType *ty = llvm::FunctionType::get(
CGM.
VoidTy,
false);
193 llvm::raw_svector_ostream Out(FnName);
206 llvm::CallInst *call = CGF.
Builder.CreateCall(dtor, addr);
209 if (llvm::Function *dtorFn =
210 dyn_cast<llvm::Function>(dtor->stripPointerCasts()))
211 call->setCallingConv(dtorFn->getCallingConv());
220 llvm::Constant *dtor,
221 llvm::Constant *addr) {
226 llvm::FunctionType *atexitTy =
227 llvm::FunctionType::get(
IntTy, dtorStub->getType(),
false);
229 llvm::Constant *atexit =
231 if (llvm::Function *atexitFn = dyn_cast<llvm::Function>(atexit))
232 atexitFn->setDoesNotThrow();
238 llvm::GlobalVariable *DeclPtr,
245 "this initialization requires a guard variable, which "
246 "the kernel does not support");
259 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
260 Fn->setSection(Section);
268 Fn->setDoesNotThrow();
271 if (
getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
272 SanitizerKind::KernelAddress))
273 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
274 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread))
275 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
276 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory))
277 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
278 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack))
279 Fn->addFnAttr(llvm::Attribute::SafeStack);
288 void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *D,
289 llvm::GlobalVariable *GV,
290 llvm::Function *InitFunc,
292 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
293 TheModule, InitFunc->getType(),
true,
294 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
295 PtrArray->setSection(ISA->getSection());
299 if (llvm::Comdat *
C = GV->getComdat())
300 PtrArray->setComdat(
C);
304 CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *D,
305 llvm::GlobalVariable *Addr,
308 auto I = DelayedCXXInitPosition.find(D);
309 if (
I != DelayedCXXInitPosition.end() &&
I->second == ~0U)
312 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
315 llvm::raw_svector_ostream Out(FnName);
325 auto *ISA = D->
getAttr<InitSegAttr>();
329 llvm::GlobalVariable *COMDATKey =
339 CXXThreadLocalInits.push_back(Fn);
340 CXXThreadLocalInitVars.push_back(D);
341 }
else if (PerformInit && ISA) {
342 EmitPointerToInitFunc(D, Addr, Fn, ISA);
343 }
else if (
auto *IPA = D->
getAttr<InitPriorityAttr>()) {
345 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
359 AddGlobalCtor(Fn, 65535, COMDATKey);
360 }
else if (D->
hasAttr<SelectAnyAttr>()) {
364 AddGlobalCtor(Fn, 65535, COMDATKey);
366 I = DelayedCXXInitPosition.find(D);
367 if (
I == DelayedCXXInitPosition.end()) {
368 CXXGlobalInits.push_back(Fn);
369 }
else if (
I->second != ~0U) {
370 assert(
I->second < CXXGlobalInits.size() &&
371 CXXGlobalInits[
I->second] ==
nullptr);
372 CXXGlobalInits[
I->second] = Fn;
377 DelayedCXXInitPosition[D] = ~0U;
380 void CodeGenModule::EmitCXXThreadLocalInitFunc() {
382 *
this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
384 CXXThreadLocalInits.clear();
385 CXXThreadLocalInitVars.clear();
386 CXXThreadLocals.clear();
390 CodeGenModule::EmitCXXGlobalInitFunc() {
391 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
392 CXXGlobalInits.pop_back();
394 if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
397 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
401 if (!PrioritizedCXXGlobalInits.empty()) {
403 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
404 PrioritizedCXXGlobalInits.end());
409 I = PrioritizedCXXGlobalInits.begin(),
410 E = PrioritizedCXXGlobalInits.end();
I !=
E; ) {
412 PrioE = std::upper_bound(
I + 1,
E, *
I, GlobalInitPriorityCmp());
414 LocalCXXGlobalInits.clear();
415 unsigned Priority =
I->first.priority;
418 std::string PrioritySuffix = llvm::utostr(Priority);
420 PrioritySuffix = std::string(6-PrioritySuffix.size(),
'0')+PrioritySuffix;
422 FTy,
"_GLOBAL__I_" + PrioritySuffix, FI);
424 for (;
I < PrioE; ++
I)
425 LocalCXXGlobalInits.push_back(
I->second);
428 AddGlobalCtor(Fn, Priority);
430 PrioritizedCXXGlobalInits.clear();
439 FileName = llvm::sys::path::filename(MainFile->getName());
444 for (
size_t i = 0; i < FileName.size(); ++i) {
452 FTy, llvm::Twine(
"_GLOBAL__sub_I_", FileName), FI);
457 CXXGlobalInits.clear();
460 void CodeGenModule::EmitCXXGlobalDtorFunc() {
461 if (CXXGlobalDtors.empty())
464 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
478 llvm::GlobalVariable *Addr,
487 getTypes().arrangeNullaryFunction(),
494 if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage()) {
514 llvm::BasicBlock *ExitBlock =
nullptr;
520 "guard.uninitialized");
523 Builder.CreateCondBr(Uninit, InitBlock, ExitBlock);
540 for (
unsigned i = 0, e = Decls.size(); i != e; ++i)
556 const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> >
566 for (
unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
567 llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
568 llvm::CallInst *CI =
Builder.CreateCall(Callee,
569 DtorsAndObjects[e - i - 1].second);
571 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
572 CI->setCallingConv(F->getCallingConv());
584 bool useEHCleanupForArray,
const VarDecl *VD) {
588 args.push_back(&dst);
594 FTy,
"__cxx_global_array_dtor", FI, VD->
getLocation());
600 emitDestroy(addr, type, destroyer, useEHCleanupForArray);
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
const CGFunctionInfo & arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args, const FunctionType::ExtInfo &Info, bool isVariadic)
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.
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
ID
Defines the set of possible language-specific address spaces.
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()
getNullaryFunctionInfo - Get the function info for a void() function with standard CC...
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.
bool isExternallyVisible() const
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)
Creates clause with a list of variables VL and a linear step Step.
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.
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
SourceLocation getLocation() const
LValue - This represents an lvalue references.
This class handles loading and caching of source files into memory.
A class which abstracts out some details necessary for making a call.
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.