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;
27 llvm::Constant *DeclPtr) {
30 "Should not call EmitDeclInit on a reference!");
34 CharUnits alignment = Context.getDeclAlign(&D);
61 llvm_unreachable(
"bad evaluation kind");
67 llvm::Constant *addr) {
85 assert(!D.
getTLSKind() &&
"should have rejected this");
89 llvm::Constant *
function;
90 llvm::Constant *argument;
101 argument = llvm::ConstantExpr::getBitCast(
109 argument = llvm::Constant::getNullValue(CGF.
Int8PtrTy);
118 llvm::Constant *Addr) {
131 llvm::ConstantExpr::getBitCast(Addr, CGF.
Int8PtrTy)};
132 CGF.
Builder.CreateCall(InvariantStart, Args);
136 llvm::Constant *DeclPtr,
158 unsigned ActualAddrSpace = DeclPtr->getType()->getPointerAddressSpace();
159 if (ActualAddrSpace != ExpectedAddrSpace) {
161 llvm::PointerType *PTy = llvm::PointerType::get(LTy, ExpectedAddrSpace);
162 DeclPtr = llvm::ConstantExpr::getAddrSpaceCast(DeclPtr, PTy);
168 &D, DeclPtr, D.
getAttr<OMPThreadPrivateDeclAttr>()->getLocation(),
179 assert(PerformInit &&
"cannot have constant initializer which needs "
180 "destruction for reference");
189 llvm::Constant *dtor,
190 llvm::Constant *addr) {
192 llvm::FunctionType *ty = llvm::FunctionType::get(
CGM.
VoidTy,
false);
195 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");
252 llvm::FunctionType *FTy,
const Twine &Name,
SourceLocation Loc,
bool TLS) {
258 if (
const char *Section =
getTarget().getStaticInitSectionSpecifier())
259 Fn->setSection(Section);
267 Fn->setDoesNotThrow();
270 if (
getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
271 SanitizerKind::KernelAddress))
272 Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
273 if (
getLangOpts().Sanitize.has(SanitizerKind::Thread))
274 Fn->addFnAttr(llvm::Attribute::SanitizeThread);
275 if (
getLangOpts().Sanitize.has(SanitizerKind::Memory))
276 Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
277 if (
getLangOpts().Sanitize.has(SanitizerKind::SafeStack))
278 Fn->addFnAttr(llvm::Attribute::SafeStack);
287 void CodeGenModule::EmitPointerToInitFunc(
const VarDecl *D,
288 llvm::GlobalVariable *GV,
289 llvm::Function *InitFunc,
291 llvm::GlobalVariable *PtrArray =
new llvm::GlobalVariable(
292 TheModule, InitFunc->getType(),
true,
293 llvm::GlobalValue::PrivateLinkage, InitFunc,
"__cxx_init_fn_ptr");
294 PtrArray->setSection(ISA->getSection());
298 if (llvm::Comdat *
C = GV->getComdat())
299 PtrArray->setComdat(
C);
303 CodeGenModule::EmitCXXGlobalVarDeclInitFunc(
const VarDecl *D,
304 llvm::GlobalVariable *Addr,
307 auto I = DelayedCXXInitPosition.find(D);
308 if (I != DelayedCXXInitPosition.end() && I->second == ~0U)
311 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
314 llvm::raw_svector_ostream Out(FnName);
322 auto *ISA = D->
getAttr<InitSegAttr>();
326 llvm::GlobalVariable *COMDATKey =
336 CXXThreadLocalInits.push_back(Fn);
337 CXXThreadLocalInitVars.push_back(Addr);
338 }
else if (PerformInit && ISA) {
339 EmitPointerToInitFunc(D, Addr, Fn, ISA);
340 }
else if (
auto *IPA = D->
getAttr<InitPriorityAttr>()) {
342 PrioritizedCXXGlobalInits.push_back(std::make_pair(Key, Fn));
356 AddGlobalCtor(Fn, 65535, COMDATKey);
357 }
else if (D->
hasAttr<SelectAnyAttr>()) {
361 AddGlobalCtor(Fn, 65535, COMDATKey);
363 I = DelayedCXXInitPosition.find(D);
364 if (I == DelayedCXXInitPosition.end()) {
365 CXXGlobalInits.push_back(Fn);
366 }
else if (I->second != ~0U) {
367 assert(I->second < CXXGlobalInits.size() &&
368 CXXGlobalInits[I->second] ==
nullptr);
369 CXXGlobalInits[I->second] = Fn;
374 DelayedCXXInitPosition[D] = ~0U;
377 void CodeGenModule::EmitCXXThreadLocalInitFunc() {
379 *
this, CXXThreadLocals, CXXThreadLocalInits, CXXThreadLocalInitVars);
381 CXXThreadLocalInits.clear();
382 CXXThreadLocalInitVars.clear();
383 CXXThreadLocals.clear();
387 CodeGenModule::EmitCXXGlobalInitFunc() {
388 while (!CXXGlobalInits.empty() && !CXXGlobalInits.back())
389 CXXGlobalInits.pop_back();
391 if (CXXGlobalInits.empty() && PrioritizedCXXGlobalInits.empty())
394 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
398 if (!PrioritizedCXXGlobalInits.empty()) {
400 llvm::array_pod_sort(PrioritizedCXXGlobalInits.begin(),
401 PrioritizedCXXGlobalInits.end());
406 I = PrioritizedCXXGlobalInits.begin(),
407 E = PrioritizedCXXGlobalInits.end(); I != E; ) {
409 PrioE = std::upper_bound(I + 1, E, *I, GlobalInitPriorityCmp());
411 LocalCXXGlobalInits.clear();
412 unsigned Priority = I->first.priority;
415 std::string PrioritySuffix = llvm::utostr(Priority);
417 PrioritySuffix = std::string(6-PrioritySuffix.size(),
'0')+PrioritySuffix;
419 FTy,
"_GLOBAL__I_" + PrioritySuffix);
421 for (; I < PrioE; ++I)
422 LocalCXXGlobalInits.push_back(I->second);
425 AddGlobalCtor(Fn, Priority);
427 PrioritizedCXXGlobalInits.clear();
436 FileName = llvm::sys::path::filename(MainFile->getName());
441 for (
size_t i = 0; i < FileName.size(); ++i) {
449 FTy, llvm::Twine(
"_GLOBAL__sub_I_", FileName));
454 CXXGlobalInits.clear();
457 void CodeGenModule::EmitCXXGlobalDtorFunc() {
458 if (CXXGlobalDtors.empty())
461 llvm::FunctionType *FTy = llvm::FunctionType::get(
VoidTy,
false);
473 llvm::GlobalVariable *Addr,
482 getTypes().arrangeNullaryFunction(),
489 if (Addr->hasWeakLinkage() || Addr->hasLinkOnceLinkage()) {
501 llvm::GlobalVariable *Guard) {
509 llvm::BasicBlock *ExitBlock =
nullptr;
515 "guard.uninitialized");
519 Builder.CreateStore(llvm::ConstantInt::get(GuardVal->getType(),1), Guard);
522 Builder.CreateCondBr(Uninit, InitBlock, ExitBlock);
535 for (
unsigned i = 0, e = Decls.size(); i != e; ++i)
551 const std::vector<std::pair<llvm::WeakVH, llvm::Constant*> >
561 for (
unsigned i = 0, e = DtorsAndObjects.size(); i != e; ++i) {
562 llvm::Value *Callee = DtorsAndObjects[e - i - 1].first;
563 llvm::CallInst *CI =
Builder.CreateCall(Callee,
564 DtorsAndObjects[e - i - 1].second);
566 if (llvm::Function *F = dyn_cast<llvm::Function>(Callee))
567 CI->setCallingConv(F->getCallingConv());
577 llvm::Constant *addr,
QualType type, Destroyer *destroyer,
578 bool useEHCleanupForArray,
const VarDecl *VD) {
582 args.push_back(&dst);
588 FTy,
"__cxx_global_array_dtor", VD->
getLocation());
594 emitDestroy(addr, type, destroyer, useEHCleanupForArray);
llvm::IntegerType * IntTy
int
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)
CodeGenTypes & getTypes()
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
DestructionKind isDestructedType() const
llvm::Module & getModule() const
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, IsZeroed_t isZeroed=IsNotZeroed)
static void EmitDeclDestroy(CodeGenFunction &CGF, const VarDecl &D, llvm::Constant *addr)
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)
const Expr * getInit() const
const LangOptions & getLangOpts() const
const CGFunctionInfo & arrangeFreeFunctionDeclaration(QualType ResTy, const FunctionArgList &Args, const FunctionType::ExtInfo &Info, bool isVariadic)
virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest)=0
TLSKind getTLSKind() const
llvm::Value * EmitObjCAutoreleasePoolPush()
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
llvm::Type * ConvertTypeForMem(QualType T)
static LLVM_READONLY bool isPreprocessingNumberBody(unsigned char c)
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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)
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. Otherwise switch to an artificial debug location that has a v...
LValue MakeAddrLValue(llvm::Value *V, QualType T, CharUnits Alignment=CharUnits())
virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest, bool threadlocal=false)=0
llvm::PointerType * VoidPtrTy
bool needsEHCleanup(QualType::DestructionKind kind)
void registerGlobalDtorWithAtExit(const VarDecl &D, llvm::Constant *fn, llvm::Constant *addr)
Register a global destructor using the C atexit runtime function.
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr * > VL, ArrayRef< Expr * > IL, Expr *Step, Expr *CalcStep)
Creates clause with a list of variables VL and a linear step Step.
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.
llvm::Function * generateDestroyHelper(llvm::Constant *addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray, const VarDecl *VD)
bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor)
llvm::GlobalValue * getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type, const CGFunctionInfo *FnInfo=nullptr, llvm::FunctionType *FnType=nullptr, bool DontDefer=false)
Return the address of the constructor/destructor of the given type.
void GenerateCXXGlobalInitFunc(llvm::Function *Fn, ArrayRef< llvm::Function * > CXXThreadLocals, llvm::GlobalVariable *Guard=nullptr)
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
llvm::CallInst * EmitNounwindRuntimeCall(llvm::Value *callee, const Twine &name="")
void emitDestroy(llvm::Value *addr, QualType type, Destroyer *destroyer, bool useEHCleanupForArray)
const TargetInfo & getTarget() const
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)
CGObjCRuntime & getObjCRuntime()
Return a reference to the configured Objective-C runtime.
static TypeEvaluationKind getEvaluationKind(QualType T)
void SetLLVMFunctionAttributes(const Decl *D, const CGFunctionInfo &Info, llvm::Function *F)
Set the LLVM function attributes (sext, zext, etc).
CGCXXABI & getCXXABI() const
Enters a new scope for capturing cleanups, all of which will be executed once the scope is exited...
const CGFunctionInfo & arrangeNullaryFunction()
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
ASTContext & getContext() const
virtual void registerGlobalDtor(CodeGenFunction &CGF, const VarDecl &D, llvm::Constant *Dtor, llvm::Constant *Addr)=0
bool isExternallyVisible() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys=None)
void EmitCXXGlobalVarDeclInit(const VarDecl &D, llvm::Constant *DeclPtr, bool PerformInit)
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
virtual void EmitThreadLocalInitFuncs(CodeGenModule &CGM, ArrayRef< std::pair< const VarDecl *, llvm::GlobalVariable * >> CXXThreadLocals, ArrayRef< llvm::Function * > CXXThreadLocalInits, ArrayRef< llvm::GlobalVariable * > CXXThreadLocalInitVars)=0
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. The SourceManager can decode this to get at the full include stack...
llvm::Constant * createAtExitStub(const VarDecl &VD, llvm::Constant *Dtor, llvm::Constant *Addr)
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())
SourceLocation getExprLoc() const LLVM_READONLY
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
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.
SourceLocation getLocStart() const LLVM_READONLY
static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D, llvm::Constant *DeclPtr)
void EmitStoreOfScalar(llvm::Value *Value, llvm::Value *Addr, bool Volatile, unsigned Alignment, QualType Ty, llvm::MDNode *TBAAInfo=nullptr, bool isInit=false, QualType TBAABaseTy=QualType(), uint64_t TBAAOffset=0)
bool isInSanitizerBlacklist(llvm::Function *Fn, SourceLocation Loc) const
void EmitAggExpr(const Expr *E, AggValueSlot AS)
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)
SourceManager & getSourceManager()
Represents a C++ struct/union/class.
bool isObjCStrong() const
void ForceCleanup()
Force the emission of cleanups now, instead of waiting until this object is destroyed.
llvm::Function * CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name, SourceLocation Loc=SourceLocation(), bool TLS=false)
void EmitObjCAutoreleasePoolCleanup(llvm::Value *Ptr)
unsigned getTargetAddressSpace(QualType T) const
static ApplyDebugLocation CreateEmpty(CodeGenFunction &CGF)
CodeGenTypes & getTypes() const
SourceLocation getLocation() const
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)
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.