1ec2b103cSEd Schouten //===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- C++ -*-===// 2ec2b103cSEd Schouten // 322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6ec2b103cSEd Schouten // 7ec2b103cSEd Schouten //===----------------------------------------------------------------------===// 8ec2b103cSEd Schouten // 9ec2b103cSEd Schouten // This is the internal per-translation-unit state used for llvm translation. 10ec2b103cSEd Schouten // 11ec2b103cSEd Schouten //===----------------------------------------------------------------------===// 12ec2b103cSEd Schouten 1306d4ba38SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H 1406d4ba38SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H 15ec2b103cSEd Schouten 16809500fcSDimitry Andric #include "CGVTables.h" 1745b53394SDimitry Andric #include "CodeGenTypeCache.h" 18809500fcSDimitry Andric #include "CodeGenTypes.h" 1906d4ba38SDimitry Andric #include "SanitizerMetadata.h" 20ec2b103cSEd Schouten #include "clang/AST/DeclCXX.h" 214c8b2481SRoman Divacky #include "clang/AST/DeclObjC.h" 222b6b257fSDimitry Andric #include "clang/AST/DeclOpenMP.h" 23180abc3dSDimitry Andric #include "clang/AST/GlobalDecl.h" 24bca07a45SDimitry Andric #include "clang/AST/Mangle.h" 25809500fcSDimitry Andric #include "clang/Basic/ABI.h" 26809500fcSDimitry Andric #include "clang/Basic/LangOptions.h" 27344a3780SDimitry Andric #include "clang/Basic/NoSanitizeList.h" 28b1c73532SDimitry Andric #include "clang/Basic/ProfileList.h" 29cfca06d7SDimitry Andric #include "clang/Basic/TargetInfo.h" 307442d6faSDimitry Andric #include "clang/Basic/XRayLists.h" 31344a3780SDimitry Andric #include "clang/Lex/PreprocessorOptions.h" 32ec2b103cSEd Schouten #include "llvm/ADT/DenseMap.h" 337fa27ce4SDimitry Andric #include "llvm/ADT/MapVector.h" 34809500fcSDimitry Andric #include "llvm/ADT/SetVector.h" 35dd5132ceSRoman Divacky #include "llvm/ADT/SmallPtrSet.h" 36809500fcSDimitry Andric #include "llvm/ADT/StringMap.h" 37809500fcSDimitry Andric #include "llvm/IR/Module.h" 389f4dbff6SDimitry Andric #include "llvm/IR/ValueHandle.h" 392b6b257fSDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h" 40e3b55780SDimitry Andric #include <optional> 41ec2b103cSEd Schouten 42ec2b103cSEd Schouten namespace llvm { 43ec2b103cSEd Schouten class Module; 44ec2b103cSEd Schouten class Constant; 45180abc3dSDimitry Andric class ConstantInt; 46ec2b103cSEd Schouten class Function; 47ec2b103cSEd Schouten class GlobalValue; 4813cc256eSDimitry Andric class DataLayout; 49ec2b103cSEd Schouten class FunctionType; 504c8b2481SRoman Divacky class LLVMContext; 519f4dbff6SDimitry Andric class IndexedInstrProfReader; 5208e8dd7bSDimitry Andric 5308e8dd7bSDimitry Andric namespace vfs { 5408e8dd7bSDimitry Andric class FileSystem; 5508e8dd7bSDimitry Andric } 56ec2b103cSEd Schouten } 57ec2b103cSEd Schouten 58ec2b103cSEd Schouten namespace clang { 59ec2b103cSEd Schouten class ASTContext; 60809500fcSDimitry Andric class AtomicType; 61ec2b103cSEd Schouten class FunctionDecl; 62ec2b103cSEd Schouten class IdentifierInfo; 63ec2b103cSEd Schouten class ObjCImplementationDecl; 64ec2b103cSEd Schouten class ObjCEncodeExpr; 65ec2b103cSEd Schouten class BlockExpr; 66ecb7e5c8SRoman Divacky class CharUnits; 67ec2b103cSEd Schouten class Decl; 68ec2b103cSEd Schouten class Expr; 69ec2b103cSEd Schouten class Stmt; 70ec2b103cSEd Schouten class StringLiteral; 71ec2b103cSEd Schouten class NamedDecl; 72ac9a064cSDimitry Andric class PointerAuthSchema; 73ec2b103cSEd Schouten class ValueDecl; 74ec2b103cSEd Schouten class VarDecl; 75ec2b103cSEd Schouten class LangOptions; 76b3d5a323SRoman Divacky class CodeGenOptions; 77c192b3dcSDimitry Andric class HeaderSearchOptions; 7836981b17SDimitry Andric class DiagnosticsEngine; 79ec2b103cSEd Schouten class AnnotateAttr; 80ec2b103cSEd Schouten class CXXDestructorDecl; 81809500fcSDimitry Andric class Module; 8206d4ba38SDimitry Andric class CoverageSourceInfo; 83706b4fc4SDimitry Andric class InitSegAttr; 84ec2b103cSEd Schouten 85ec2b103cSEd Schouten namespace CodeGen { 86ec2b103cSEd Schouten 87ec2b103cSEd Schouten class CodeGenFunction; 88bca07a45SDimitry Andric class CodeGenTBAA; 893d1dcd9bSDimitry Andric class CGCXXABI; 90ec2b103cSEd Schouten class CGDebugInfo; 91ec2b103cSEd Schouten class CGObjCRuntime; 9236981b17SDimitry Andric class CGOpenCLRuntime; 939f4dbff6SDimitry Andric class CGOpenMPRuntime; 9436981b17SDimitry Andric class CGCUDARuntime; 95145449b1SDimitry Andric class CGHLSLRuntime; 9606d4ba38SDimitry Andric class CoverageMappingModuleGen; 972b6b257fSDimitry Andric class TargetCodeGenInfo; 98ec2b103cSEd Schouten 99bab175ecSDimitry Andric enum ForDefinition_t : bool { 100bab175ecSDimitry Andric NotForDefinition = false, 101bab175ecSDimitry Andric ForDefinition = true 102bab175ecSDimitry Andric }; 103bab175ecSDimitry Andric 104344a3780SDimitry Andric struct OrderGlobalInitsOrStermFinalizers { 1054ba67500SRoman Divacky unsigned int priority; 1064ba67500SRoman Divacky unsigned int lex_order; OrderGlobalInitsOrStermFinalizersOrderGlobalInitsOrStermFinalizers107344a3780SDimitry Andric OrderGlobalInitsOrStermFinalizers(unsigned int p, unsigned int l) 1084ba67500SRoman Divacky : priority(p), lex_order(l) {} 1094ba67500SRoman Divacky 110344a3780SDimitry Andric bool operator==(const OrderGlobalInitsOrStermFinalizers &RHS) const { 1119f4dbff6SDimitry Andric return priority == RHS.priority && lex_order == RHS.lex_order; 1124ba67500SRoman Divacky } 1134ba67500SRoman Divacky 114344a3780SDimitry Andric bool operator<(const OrderGlobalInitsOrStermFinalizers &RHS) const { 1159f4dbff6SDimitry Andric return std::tie(priority, lex_order) < 1169f4dbff6SDimitry Andric std::tie(RHS.priority, RHS.lex_order); 1174ba67500SRoman Divacky } 1184ba67500SRoman Divacky }; 1194ba67500SRoman Divacky 12045b53394SDimitry Andric struct ObjCEntrypoints { ObjCEntrypointsObjCEntrypoints12145b53394SDimitry Andric ObjCEntrypoints() { memset(this, 0, sizeof(*this)); } 12229cafa66SDimitry Andric 123676fbe81SDimitry Andric /// void objc_alloc(id); 12422989816SDimitry Andric llvm::FunctionCallee objc_alloc; 125676fbe81SDimitry Andric 126676fbe81SDimitry Andric /// void objc_allocWithZone(id); 12722989816SDimitry Andric llvm::FunctionCallee objc_allocWithZone; 12822989816SDimitry Andric 12922989816SDimitry Andric /// void objc_alloc_init(id); 13022989816SDimitry Andric llvm::FunctionCallee objc_alloc_init; 131676fbe81SDimitry Andric 132180abc3dSDimitry Andric /// void objc_autoreleasePoolPop(void*); 13322989816SDimitry Andric llvm::FunctionCallee objc_autoreleasePoolPop; 134180abc3dSDimitry Andric 135676fbe81SDimitry Andric /// void objc_autoreleasePoolPop(void*); 136676fbe81SDimitry Andric /// Note this method is used when we are using exception handling 13722989816SDimitry Andric llvm::FunctionCallee objc_autoreleasePoolPopInvoke; 138676fbe81SDimitry Andric 139180abc3dSDimitry Andric /// void *objc_autoreleasePoolPush(void); 14022989816SDimitry Andric llvm::Function *objc_autoreleasePoolPush; 141180abc3dSDimitry Andric 142180abc3dSDimitry Andric /// id objc_autorelease(id); 14322989816SDimitry Andric llvm::Function *objc_autorelease; 144180abc3dSDimitry Andric 145676fbe81SDimitry Andric /// id objc_autorelease(id); 146676fbe81SDimitry Andric /// Note this is the runtime method not the intrinsic. 14722989816SDimitry Andric llvm::FunctionCallee objc_autoreleaseRuntimeFunction; 148676fbe81SDimitry Andric 149180abc3dSDimitry Andric /// id objc_autoreleaseReturnValue(id); 15022989816SDimitry Andric llvm::Function *objc_autoreleaseReturnValue; 151180abc3dSDimitry Andric 152180abc3dSDimitry Andric /// void objc_copyWeak(id *dest, id *src); 15322989816SDimitry Andric llvm::Function *objc_copyWeak; 154180abc3dSDimitry Andric 155180abc3dSDimitry Andric /// void objc_destroyWeak(id*); 15622989816SDimitry Andric llvm::Function *objc_destroyWeak; 157180abc3dSDimitry Andric 158180abc3dSDimitry Andric /// id objc_initWeak(id*, id); 15922989816SDimitry Andric llvm::Function *objc_initWeak; 160180abc3dSDimitry Andric 161180abc3dSDimitry Andric /// id objc_loadWeak(id*); 16222989816SDimitry Andric llvm::Function *objc_loadWeak; 163180abc3dSDimitry Andric 164180abc3dSDimitry Andric /// id objc_loadWeakRetained(id*); 16522989816SDimitry Andric llvm::Function *objc_loadWeakRetained; 166180abc3dSDimitry Andric 167180abc3dSDimitry Andric /// void objc_moveWeak(id *dest, id *src); 16822989816SDimitry Andric llvm::Function *objc_moveWeak; 169180abc3dSDimitry Andric 170180abc3dSDimitry Andric /// id objc_retain(id); 17122989816SDimitry Andric llvm::Function *objc_retain; 172180abc3dSDimitry Andric 173676fbe81SDimitry Andric /// id objc_retain(id); 174676fbe81SDimitry Andric /// Note this is the runtime method not the intrinsic. 17522989816SDimitry Andric llvm::FunctionCallee objc_retainRuntimeFunction; 176676fbe81SDimitry Andric 177180abc3dSDimitry Andric /// id objc_retainAutorelease(id); 17822989816SDimitry Andric llvm::Function *objc_retainAutorelease; 179180abc3dSDimitry Andric 180180abc3dSDimitry Andric /// id objc_retainAutoreleaseReturnValue(id); 18122989816SDimitry Andric llvm::Function *objc_retainAutoreleaseReturnValue; 182180abc3dSDimitry Andric 183180abc3dSDimitry Andric /// id objc_retainAutoreleasedReturnValue(id); 18422989816SDimitry Andric llvm::Function *objc_retainAutoreleasedReturnValue; 185180abc3dSDimitry Andric 186180abc3dSDimitry Andric /// id objc_retainBlock(id); 18722989816SDimitry Andric llvm::Function *objc_retainBlock; 188180abc3dSDimitry Andric 189180abc3dSDimitry Andric /// void objc_release(id); 19022989816SDimitry Andric llvm::Function *objc_release; 191180abc3dSDimitry Andric 192676fbe81SDimitry Andric /// void objc_release(id); 193676fbe81SDimitry Andric /// Note this is the runtime method not the intrinsic. 19422989816SDimitry Andric llvm::FunctionCallee objc_releaseRuntimeFunction; 195676fbe81SDimitry Andric 196eb285452SDimitry Andric /// void objc_storeStrong(id*, id); 19722989816SDimitry Andric llvm::Function *objc_storeStrong; 198180abc3dSDimitry Andric 199180abc3dSDimitry Andric /// id objc_storeWeak(id*, id); 20022989816SDimitry Andric llvm::Function *objc_storeWeak; 201180abc3dSDimitry Andric 2022b6b257fSDimitry Andric /// id objc_unsafeClaimAutoreleasedReturnValue(id); 20322989816SDimitry Andric llvm::Function *objc_unsafeClaimAutoreleasedReturnValue; 2042b6b257fSDimitry Andric 205180abc3dSDimitry Andric /// A void(void) inline asm to use to mark that the return value of 206180abc3dSDimitry Andric /// a call will be immediately retain. 207180abc3dSDimitry Andric llvm::InlineAsm *retainAutoreleasedReturnValueMarker; 208809500fcSDimitry Andric 209809500fcSDimitry Andric /// void clang.arc.use(...); 21022989816SDimitry Andric llvm::Function *clang_arc_use; 211344a3780SDimitry Andric 212344a3780SDimitry Andric /// void clang.arc.noop.use(...); 213344a3780SDimitry Andric llvm::Function *clang_arc_noop_use; 214180abc3dSDimitry Andric }; 215180abc3dSDimitry Andric 2169f4dbff6SDimitry Andric /// This class records statistics on instrumentation based profiling. 2179f4dbff6SDimitry Andric class InstrProfStats { 218b1c73532SDimitry Andric uint32_t VisitedInMainFile = 0; 219b1c73532SDimitry Andric uint32_t MissingInMainFile = 0; 220b1c73532SDimitry Andric uint32_t Visited = 0; 221b1c73532SDimitry Andric uint32_t Missing = 0; 222b1c73532SDimitry Andric uint32_t Mismatched = 0; 2239f4dbff6SDimitry Andric 2249f4dbff6SDimitry Andric public: 225b1c73532SDimitry Andric InstrProfStats() = default; 2269f4dbff6SDimitry Andric /// Record that we've visited a function and whether or not that function was 2279f4dbff6SDimitry Andric /// in the main source file. addVisited(bool MainFile)2289f4dbff6SDimitry Andric void addVisited(bool MainFile) { 2299f4dbff6SDimitry Andric if (MainFile) 2309f4dbff6SDimitry Andric ++VisitedInMainFile; 2319f4dbff6SDimitry Andric ++Visited; 2329f4dbff6SDimitry Andric } 2339f4dbff6SDimitry Andric /// Record that a function we've visited has no profile data. addMissing(bool MainFile)2349f4dbff6SDimitry Andric void addMissing(bool MainFile) { 2359f4dbff6SDimitry Andric if (MainFile) 2369f4dbff6SDimitry Andric ++MissingInMainFile; 2379f4dbff6SDimitry Andric ++Missing; 2389f4dbff6SDimitry Andric } 2399f4dbff6SDimitry Andric /// Record that a function we've visited has mismatched profile data. addMismatched(bool MainFile)2409f4dbff6SDimitry Andric void addMismatched(bool MainFile) { ++Mismatched; } 2419f4dbff6SDimitry Andric /// Whether or not the stats we've gathered indicate any potential problems. hasDiagnostics()2429f4dbff6SDimitry Andric bool hasDiagnostics() { return Missing || Mismatched; } 2439f4dbff6SDimitry Andric /// Report potential problems we've found to \c Diags. 2449f4dbff6SDimitry Andric void reportDiagnostics(DiagnosticsEngine &Diags, StringRef MainFile); 2459f4dbff6SDimitry Andric }; 2469f4dbff6SDimitry Andric 24745b53394SDimitry Andric /// A pair of helper functions for a __block variable. 24845b53394SDimitry Andric class BlockByrefHelpers : public llvm::FoldingSetNode { 24945b53394SDimitry Andric // MSVC requires this type to be complete in order to process this 25045b53394SDimitry Andric // header. 25145b53394SDimitry Andric public: 25245b53394SDimitry Andric llvm::Constant *CopyHelper; 25345b53394SDimitry Andric llvm::Constant *DisposeHelper; 25445b53394SDimitry Andric 25545b53394SDimitry Andric /// The alignment of the field. This is important because 25645b53394SDimitry Andric /// different offsets to the field within the byref struct need to 25745b53394SDimitry Andric /// have different helper functions. 25845b53394SDimitry Andric CharUnits Alignment; 25945b53394SDimitry Andric BlockByrefHelpers(CharUnits alignment)26022989816SDimitry Andric BlockByrefHelpers(CharUnits alignment) 26122989816SDimitry Andric : CopyHelper(nullptr), DisposeHelper(nullptr), Alignment(alignment) {} 26245b53394SDimitry Andric BlockByrefHelpers(const BlockByrefHelpers &) = default; 26345b53394SDimitry Andric virtual ~BlockByrefHelpers(); 26445b53394SDimitry Andric Profile(llvm::FoldingSetNodeID & id)26545b53394SDimitry Andric void Profile(llvm::FoldingSetNodeID &id) const { 26645b53394SDimitry Andric id.AddInteger(Alignment.getQuantity()); 26745b53394SDimitry Andric profileImpl(id); 26845b53394SDimitry Andric } 26945b53394SDimitry Andric virtual void profileImpl(llvm::FoldingSetNodeID &id) const = 0; 27045b53394SDimitry Andric needsCopy()27145b53394SDimitry Andric virtual bool needsCopy() const { return true; } 27245b53394SDimitry Andric virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src) = 0; 27345b53394SDimitry Andric needsDispose()27445b53394SDimitry Andric virtual bool needsDispose() const { return true; } 27545b53394SDimitry Andric virtual void emitDispose(CodeGenFunction &CGF, Address field) = 0; 27645b53394SDimitry Andric }; 27745b53394SDimitry Andric 2789f4dbff6SDimitry Andric /// This class organizes the cross-function state that is used while generating 2799f4dbff6SDimitry Andric /// LLVM code. 280bca07a45SDimitry Andric class CodeGenModule : public CodeGenTypeCache { 2815e20cdd8SDimitry Andric CodeGenModule(const CodeGenModule &) = delete; 2825e20cdd8SDimitry Andric void operator=(const CodeGenModule &) = delete; 283ec2b103cSEd Schouten 28406d4ba38SDimitry Andric public: 2859f4dbff6SDimitry Andric struct Structor { StructorStructor286e3b55780SDimitry Andric Structor() 287e3b55780SDimitry Andric : Priority(0), LexOrder(~0u), Initializer(nullptr), 288e3b55780SDimitry Andric AssociatedData(nullptr) {} StructorStructor289e3b55780SDimitry Andric Structor(int Priority, unsigned LexOrder, llvm::Constant *Initializer, 2909f4dbff6SDimitry Andric llvm::Constant *AssociatedData) 291e3b55780SDimitry Andric : Priority(Priority), LexOrder(LexOrder), Initializer(Initializer), 2929f4dbff6SDimitry Andric AssociatedData(AssociatedData) {} 2939f4dbff6SDimitry Andric int Priority; 294e3b55780SDimitry Andric unsigned LexOrder; 2959f4dbff6SDimitry Andric llvm::Constant *Initializer; 2969f4dbff6SDimitry Andric llvm::Constant *AssociatedData; 2979f4dbff6SDimitry Andric }; 2989f4dbff6SDimitry Andric 2999f4dbff6SDimitry Andric typedef std::vector<Structor> CtorList; 300ec2b103cSEd Schouten 30106d4ba38SDimitry Andric private: 302ec2b103cSEd Schouten ASTContext &Context; 303dbe13110SDimitry Andric const LangOptions &LangOpts; 30408e8dd7bSDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; // Only used for debug info. 305c192b3dcSDimitry Andric const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info. 306c192b3dcSDimitry Andric const PreprocessorOptions &PreprocessorOpts; // Only used for debug info. 307b3d5a323SRoman Divacky const CodeGenOptions &CodeGenOpts; 308cfca06d7SDimitry Andric unsigned NumAutoVarInit = 0; 309ec2b103cSEd Schouten llvm::Module &TheModule; 31036981b17SDimitry Andric DiagnosticsEngine &Diags; 3116a037251SDimitry Andric const TargetInfo &Target; 3129f4dbff6SDimitry Andric std::unique_ptr<CGCXXABI> ABI; 3136a037251SDimitry Andric llvm::LLVMContext &VMContext; 3146f8fc217SDimitry Andric std::string ModuleNameHash; 3154b4fe385SDimitry Andric bool CXX20ModuleInits = false; 3162b6b257fSDimitry Andric std::unique_ptr<CodeGenTBAA> TBAA; 3174c8b2481SRoman Divacky 3182b6b257fSDimitry Andric mutable std::unique_ptr<TargetCodeGenInfo> TheTargetCodeGenInfo; 3196a037251SDimitry Andric 3206a037251SDimitry Andric // This should not be moved earlier, since its initialization depends on some 3216a037251SDimitry Andric // of the previous reference members being already initialized and also checks 3226a037251SDimitry Andric // if TheTargetCodeGenInfo is NULL 323e6b73279SDimitry Andric std::unique_ptr<CodeGenTypes> Types; 3246a037251SDimitry Andric 3259f4dbff6SDimitry Andric /// Holds information about C++ vtables. 32611d2b2d2SRoman Divacky CodeGenVTables VTables; 3274c8b2481SRoman Divacky 3282b6b257fSDimitry Andric std::unique_ptr<CGObjCRuntime> ObjCRuntime; 3292b6b257fSDimitry Andric std::unique_ptr<CGOpenCLRuntime> OpenCLRuntime; 3302b6b257fSDimitry Andric std::unique_ptr<CGOpenMPRuntime> OpenMPRuntime; 3312b6b257fSDimitry Andric std::unique_ptr<CGCUDARuntime> CUDARuntime; 332145449b1SDimitry Andric std::unique_ptr<CGHLSLRuntime> HLSLRuntime; 3332b6b257fSDimitry Andric std::unique_ptr<CGDebugInfo> DebugInfo; 3342b6b257fSDimitry Andric std::unique_ptr<ObjCEntrypoints> ObjCData; 3352b6b257fSDimitry Andric llvm::MDNode *NoObjCARCExceptionsMetadata = nullptr; 3369f4dbff6SDimitry Andric std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader; 3379f4dbff6SDimitry Andric InstrProfStats PGOStats; 3382b6b257fSDimitry Andric std::unique_ptr<llvm::SanitizerStatReport> SanStats; 339ec2b103cSEd Schouten 3409f4dbff6SDimitry Andric // A set of references that have only been seen via a weakref so far. This is 3419f4dbff6SDimitry Andric // used to remove the weak of the reference if we ever see a direct reference 3429f4dbff6SDimitry Andric // or a definition. 343dd5132ceSRoman Divacky llvm::SmallPtrSet<llvm::GlobalValue*, 10> WeakRefReferences; 344dd5132ceSRoman Divacky 3459f4dbff6SDimitry Andric /// This contains all the decls which have definitions but/ which are deferred 3469f4dbff6SDimitry Andric /// for emission and therefore should only be output if they are actually 3479f4dbff6SDimitry Andric /// used. If a decl is in this, then it is known to have not been referenced 3489f4dbff6SDimitry Andric /// yet. 3496f8fc217SDimitry Andric llvm::DenseMap<StringRef, GlobalDecl> DeferredDecls; 350ec2b103cSEd Schouten 351ac9a064cSDimitry Andric llvm::StringSet<llvm::BumpPtrAllocator> DeferredResolversToEmit; 352ac9a064cSDimitry Andric 3539f4dbff6SDimitry Andric /// This is a list of deferred decls which we have seen that *are* actually 3549f4dbff6SDimitry Andric /// referenced. These get code generated when the module is done. 35557091882SDimitry Andric std::vector<GlobalDecl> DeferredDeclsToEmit; addDeferredDeclToEmit(GlobalDecl GD)35657091882SDimitry Andric void addDeferredDeclToEmit(GlobalDecl GD) { 35757091882SDimitry Andric DeferredDeclsToEmit.emplace_back(GD); 3581f917f69SDimitry Andric addEmittedDeferredDecl(GD); 3591f917f69SDimitry Andric } 3601f917f69SDimitry Andric 3611f917f69SDimitry Andric /// Decls that were DeferredDecls and have now been emitted. 3621f917f69SDimitry Andric llvm::DenseMap<llvm::StringRef, GlobalDecl> EmittedDeferredDecls; 3631f917f69SDimitry Andric addEmittedDeferredDecl(GlobalDecl GD)3641f917f69SDimitry Andric void addEmittedDeferredDecl(GlobalDecl GD) { 365b1c73532SDimitry Andric // Reemission is only needed in incremental mode. 366b1c73532SDimitry Andric if (!Context.getLangOpts().IncrementalExtensions) 3671f917f69SDimitry Andric return; 368b1c73532SDimitry Andric 369b1c73532SDimitry Andric // Assume a linkage by default that does not need reemission. 370b1c73532SDimitry Andric auto L = llvm::GlobalValue::ExternalLinkage; 371b1c73532SDimitry Andric if (llvm::isa<FunctionDecl>(GD.getDecl())) 372b1c73532SDimitry Andric L = getFunctionLinkage(GD); 373b1c73532SDimitry Andric else if (auto *VD = llvm::dyn_cast<VarDecl>(GD.getDecl())) 374b1c73532SDimitry Andric L = getLLVMLinkageVarDefinition(VD); 375b1c73532SDimitry Andric 376b1c73532SDimitry Andric if (llvm::GlobalValue::isInternalLinkage(L) || 377b1c73532SDimitry Andric llvm::GlobalValue::isLinkOnceLinkage(L) || 3781f917f69SDimitry Andric llvm::GlobalValue::isWeakLinkage(L)) { 3791f917f69SDimitry Andric EmittedDeferredDecls[getMangledName(GD)] = GD; 3801f917f69SDimitry Andric } 3819f4dbff6SDimitry Andric } 382ec2b103cSEd Schouten 383bfef3995SDimitry Andric /// List of alias we have emitted. Used to make sure that what they point to 384bfef3995SDimitry Andric /// is defined once we get to the end of the of the translation unit. 385bfef3995SDimitry Andric std::vector<GlobalDecl> Aliases; 386bfef3995SDimitry Andric 387145449b1SDimitry Andric /// List of multiversion functions to be emitted. This list is processed in 388145449b1SDimitry Andric /// conjunction with other deferred symbols and is used to ensure that 389145449b1SDimitry Andric /// multiversion function resolvers and ifuncs are defined and emitted. 39048675466SDimitry Andric std::vector<GlobalDecl> MultiVersionFuncs; 39148675466SDimitry Andric 3927fa27ce4SDimitry Andric llvm::MapVector<StringRef, llvm::TrackingVH<llvm::Constant>> Replacements; 393bfef3995SDimitry Andric 39445b53394SDimitry Andric /// List of global values to be replaced with something else. Used when we 39545b53394SDimitry Andric /// want to replace a GlobalValue but can't identify it by its mangled name 39645b53394SDimitry Andric /// anymore (because the name is already taken). 39745b53394SDimitry Andric llvm::SmallVector<std::pair<llvm::GlobalValue *, llvm::Constant *>, 8> 39845b53394SDimitry Andric GlobalValReplacements; 39945b53394SDimitry Andric 40022989816SDimitry Andric /// Variables for which we've emitted globals containing their constant 40122989816SDimitry Andric /// values along with the corresponding globals, for opportunistic reuse. 40222989816SDimitry Andric llvm::DenseMap<const VarDecl*, llvm::GlobalVariable*> InitializerConstants; 40322989816SDimitry Andric 40445b53394SDimitry Andric /// Set of global decls for which we already diagnosed mangled name conflict. 40545b53394SDimitry Andric /// Required to not issue a warning (on a mangling conflict) multiple times 40645b53394SDimitry Andric /// for the same decl. 40745b53394SDimitry Andric llvm::DenseSet<GlobalDecl> DiagnosedConflictingDefinitions; 40845b53394SDimitry Andric 4099f4dbff6SDimitry Andric /// A queue of (optional) vtables to consider emitting. 410809500fcSDimitry Andric std::vector<const CXXRecordDecl*> DeferredVTables; 411809500fcSDimitry Andric 412416ada0fSDimitry Andric /// A queue of (optional) vtables that may be emitted opportunistically. 413416ada0fSDimitry Andric std::vector<const CXXRecordDecl *> OpportunisticVTables; 414416ada0fSDimitry Andric 4159f4dbff6SDimitry Andric /// List of global values which are required to be present in the object file; 4169f4dbff6SDimitry Andric /// bitcast to i8*. This is used for forcing visibility of symbols which may 4179f4dbff6SDimitry Andric /// otherwise be optimized out. 41857091882SDimitry Andric std::vector<llvm::WeakTrackingVH> LLVMUsed; 41957091882SDimitry Andric std::vector<llvm::WeakTrackingVH> LLVMCompilerUsed; 420ec2b103cSEd Schouten 4219f4dbff6SDimitry Andric /// Store the list of global constructors and their respective priorities to 4229f4dbff6SDimitry Andric /// be emitted when the translation unit is complete. 423ec2b103cSEd Schouten CtorList GlobalCtors; 424ec2b103cSEd Schouten 4259f4dbff6SDimitry Andric /// Store the list of global destructors and their respective priorities to be 4269f4dbff6SDimitry Andric /// emitted when the translation unit is complete. 427ec2b103cSEd Schouten CtorList GlobalDtors; 428ec2b103cSEd Schouten 4299f4dbff6SDimitry Andric /// An ordered map of canonical GlobalDecls to their mangled names. 4309f4dbff6SDimitry Andric llvm::MapVector<GlobalDecl, StringRef> MangledDeclNames; 4319f4dbff6SDimitry Andric llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings; 4324ba67500SRoman Divacky 43336981b17SDimitry Andric /// Global annotations. 434ec2b103cSEd Schouten std::vector<llvm::Constant*> Annotations; 435ec2b103cSEd Schouten 436b1c73532SDimitry Andric // Store deferred function annotations so they can be emitted at the end with 437b1c73532SDimitry Andric // most up to date ValueDecl that will have all the inherited annotations. 438ac9a064cSDimitry Andric llvm::MapVector<StringRef, const ValueDecl *> DeferredAnnotations; 439b1c73532SDimitry Andric 44036981b17SDimitry Andric /// Map used to get unique annotation strings. 44136981b17SDimitry Andric llvm::StringMap<llvm::Constant*> AnnotationStrings; 44236981b17SDimitry Andric 443b60736ecSDimitry Andric /// Used for uniquing of annotation arguments. 444b60736ecSDimitry Andric llvm::DenseMap<unsigned, llvm::Constant *> AnnotationArgs; 445b60736ecSDimitry Andric 4465e20cdd8SDimitry Andric llvm::StringMap<llvm::GlobalVariable *> CFConstantStringMap; 4479f4dbff6SDimitry Andric 4489f4dbff6SDimitry Andric llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> ConstantStringMap; 449145449b1SDimitry Andric llvm::DenseMap<const UnnamedGlobalConstantDecl *, llvm::GlobalVariable *> 450145449b1SDimitry Andric UnnamedGlobalConstantDeclMap; 451dbe13110SDimitry Andric llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap; 452dbe13110SDimitry Andric llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap; 453bfef3995SDimitry Andric llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap; 454dbe13110SDimitry Andric 455dbe13110SDimitry Andric llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap; 456dbe13110SDimitry Andric llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap; 457ec2b103cSEd Schouten 458bfef3995SDimitry Andric /// Map used to get unique type descriptor constants for sanitizers. 459bfef3995SDimitry Andric llvm::DenseMap<QualType, llvm::Constant *> TypeDescriptorMap; 460bfef3995SDimitry Andric 4616a037251SDimitry Andric /// Map used to track internal linkage functions declared within 4626a037251SDimitry Andric /// extern "C" regions. 4636a037251SDimitry Andric typedef llvm::MapVector<IdentifierInfo *, 4646a037251SDimitry Andric llvm::GlobalValue *> StaticExternCMap; 4656a037251SDimitry Andric StaticExternCMap StaticExternCValues; 4666a037251SDimitry Andric 46748675466SDimitry Andric /// thread_local variables defined or used in this TU. 46845b53394SDimitry Andric std::vector<const VarDecl *> CXXThreadLocals; 4696a037251SDimitry Andric 47048675466SDimitry Andric /// thread_local variables with initializers that need to run 4716a037251SDimitry Andric /// before any thread_local variable in this TU is odr-used. 47206d4ba38SDimitry Andric std::vector<llvm::Function *> CXXThreadLocalInits; 47345b53394SDimitry Andric std::vector<const VarDecl *> CXXThreadLocalInitVars; 4746a037251SDimitry Andric 4759f4dbff6SDimitry Andric /// Global variables with initializers that need to run before main. 47606d4ba38SDimitry Andric std::vector<llvm::Function *> CXXGlobalInits; 4774c8b2481SRoman Divacky 4783d1dcd9bSDimitry Andric /// When a C++ decl with an initializer is deferred, null is 4793d1dcd9bSDimitry Andric /// appended to CXXGlobalInits, and the index of that null is placed 4803d1dcd9bSDimitry Andric /// here so that the initializer will be performed in the correct 4815e20cdd8SDimitry Andric /// order. Once the decl is emitted, the index is replaced with ~0U to ensure 4825e20cdd8SDimitry Andric /// that we don't re-emit the initializer. 4833d1dcd9bSDimitry Andric llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition; 4843d1dcd9bSDimitry Andric 485344a3780SDimitry Andric typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *> 486344a3780SDimitry Andric GlobalInitData; 48713cc256eSDimitry Andric 488ac9a064cSDimitry Andric // When a tail call is performed on an "undefined" symbol, on PPC without pc 489ac9a064cSDimitry Andric // relative feature, the tail call is not allowed. In "EmitCall" for such 490ac9a064cSDimitry Andric // tail calls, the "undefined" symbols may be forward declarations, their 491ac9a064cSDimitry Andric // definitions are provided in the module after the callsites. For such tail 492ac9a064cSDimitry Andric // calls, diagnose message should not be emitted. 493ac9a064cSDimitry Andric llvm::SmallSetVector<std::pair<const FunctionDecl *, SourceLocation>, 4> 494ac9a064cSDimitry Andric MustTailCallUndefinedGlobals; 495ac9a064cSDimitry Andric 49613cc256eSDimitry Andric struct GlobalInitPriorityCmp { operatorGlobalInitPriorityCmp49713cc256eSDimitry Andric bool operator()(const GlobalInitData &LHS, 49813cc256eSDimitry Andric const GlobalInitData &RHS) const { 49913cc256eSDimitry Andric return LHS.first.priority < RHS.first.priority; 50013cc256eSDimitry Andric } 50113cc256eSDimitry Andric }; 50213cc256eSDimitry Andric 5039f4dbff6SDimitry Andric /// Global variables with initializers whose order of initialization is set by 5049f4dbff6SDimitry Andric /// init_priority attribute. 50513cc256eSDimitry Andric SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits; 5064ba67500SRoman Divacky 5079f4dbff6SDimitry Andric /// Global destructor functions and arguments that need to run on termination. 508cfca06d7SDimitry Andric /// When UseSinitAndSterm is set, it instead contains sterm finalizer 509cfca06d7SDimitry Andric /// functions, which also run on unloading a shared library. 510344a3780SDimitry Andric typedef std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, 511344a3780SDimitry Andric llvm::Constant *> 512344a3780SDimitry Andric CXXGlobalDtorsOrStermFinalizer_t; 513344a3780SDimitry Andric SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> 514cfca06d7SDimitry Andric CXXGlobalDtorsOrStermFinalizers; 515c0c7bca4SRoman Divacky 516344a3780SDimitry Andric typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *> 517344a3780SDimitry Andric StermFinalizerData; 518344a3780SDimitry Andric 519344a3780SDimitry Andric struct StermFinalizerPriorityCmp { operatorStermFinalizerPriorityCmp520344a3780SDimitry Andric bool operator()(const StermFinalizerData &LHS, 521344a3780SDimitry Andric const StermFinalizerData &RHS) const { 522344a3780SDimitry Andric return LHS.first.priority < RHS.first.priority; 523344a3780SDimitry Andric } 524344a3780SDimitry Andric }; 525344a3780SDimitry Andric 526344a3780SDimitry Andric /// Global variables with sterm finalizers whose order of initialization is 527344a3780SDimitry Andric /// set by init_priority attribute. 528344a3780SDimitry Andric SmallVector<StermFinalizerData, 8> PrioritizedCXXStermFinalizers; 529344a3780SDimitry Andric 53048675466SDimitry Andric /// The complete set of modules that has been imported. 531809500fcSDimitry Andric llvm::SetVector<clang::Module *> ImportedModules; 532809500fcSDimitry Andric 53348675466SDimitry Andric /// The set of modules for which the module initializers 534bab175ecSDimitry Andric /// have been emitted. 535bab175ecSDimitry Andric llvm::SmallPtrSet<clang::Module *, 16> EmittedModuleInitializers; 536bab175ecSDimitry Andric 53722989816SDimitry Andric /// A vector of metadata strings for linker options. 538325377b5SDimitry Andric SmallVector<llvm::MDNode *, 16> LinkerOptionsMetadata; 539bfef3995SDimitry Andric 54022989816SDimitry Andric /// A vector of metadata strings for dependent libraries for ELF. 54122989816SDimitry Andric SmallVector<llvm::MDNode *, 16> ELFDependentLibraries; 54222989816SDimitry Andric 54336981b17SDimitry Andric /// @name Cache for Objective-C runtime types 54436981b17SDimitry Andric /// @{ 54536981b17SDimitry Andric 5469f4dbff6SDimitry Andric /// Cached reference to the class for constant strings. This value has type 5479f4dbff6SDimitry Andric /// int * but is actually an Obj-C class pointer. 54857091882SDimitry Andric llvm::WeakTrackingVH CFConstantStringClassRef; 5494c8b2481SRoman Divacky 55048675466SDimitry Andric /// The type used to describe the state of a fast enumeration in 55136981b17SDimitry Andric /// Objective-C's for..in loop. 55236981b17SDimitry Andric QualType ObjCFastEnumerationStateType; 55336981b17SDimitry Andric 55436981b17SDimitry Andric /// @} 55536981b17SDimitry Andric 5565044f5c8SRoman Divacky /// Lazily create the Objective-C runtime 5575044f5c8SRoman Divacky void createObjCRuntime(); 5585044f5c8SRoman Divacky 55936981b17SDimitry Andric void createOpenCLRuntime(); 5609f4dbff6SDimitry Andric void createOpenMPRuntime(); 56136981b17SDimitry Andric void createCUDARuntime(); 562145449b1SDimitry Andric void createHLSLRuntime(); 56336981b17SDimitry Andric 564dbe13110SDimitry Andric bool isTriviallyRecursive(const FunctionDecl *F); 565bfef3995SDimitry Andric bool shouldEmitFunction(GlobalDecl GD); 566ac9a064cSDimitry Andric // Whether a global variable should be emitted by CUDA/HIP host/device 567ac9a064cSDimitry Andric // related attributes. 568ac9a064cSDimitry Andric bool shouldEmitCUDAGlobalVar(const VarDecl *VD) const; 569416ada0fSDimitry Andric bool shouldOpportunisticallyEmitVTables(); 570bab175ecSDimitry Andric /// Map used to be sure we don't emit the same CompoundLiteral twice. 571bab175ecSDimitry Andric llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *> 572bab175ecSDimitry Andric EmittedCompoundLiterals; 573bab175ecSDimitry Andric 574bab175ecSDimitry Andric /// Map of the global blocks we've emitted, so that we don't have to re-emit 575bab175ecSDimitry Andric /// them if the constexpr evaluator gets aggressive. 576bab175ecSDimitry Andric llvm::DenseMap<const BlockExpr *, llvm::Constant *> EmittedGlobalBlocks; 577bab175ecSDimitry Andric 5783d1dcd9bSDimitry Andric /// @name Cache for Blocks Runtime Globals 5793d1dcd9bSDimitry Andric /// @{ 5803d1dcd9bSDimitry Andric 5812b6b257fSDimitry Andric llvm::Constant *NSConcreteGlobalBlock = nullptr; 5822b6b257fSDimitry Andric llvm::Constant *NSConcreteStackBlock = nullptr; 5833d1dcd9bSDimitry Andric 58422989816SDimitry Andric llvm::FunctionCallee BlockObjectAssign = nullptr; 58522989816SDimitry Andric llvm::FunctionCallee BlockObjectDispose = nullptr; 5863d1dcd9bSDimitry Andric 5872b6b257fSDimitry Andric llvm::Type *BlockDescriptorType = nullptr; 5882b6b257fSDimitry Andric llvm::Type *GenericBlockLiteralType = nullptr; 589bca07a45SDimitry Andric 590bca07a45SDimitry Andric struct { 591bca07a45SDimitry Andric int GlobalUniqueCount; 592bca07a45SDimitry Andric } Block; 593bca07a45SDimitry Andric 594706b4fc4SDimitry Andric GlobalDecl initializedGlobalDecl; 595706b4fc4SDimitry Andric 596706b4fc4SDimitry Andric /// @} 597706b4fc4SDimitry Andric 598809500fcSDimitry Andric /// void @llvm.lifetime.start(i64 %size, i8* nocapture <ptr>) 59922989816SDimitry Andric llvm::Function *LifetimeStartFn = nullptr; 600809500fcSDimitry Andric 601809500fcSDimitry Andric /// void @llvm.lifetime.end(i64 %size, i8* nocapture <ptr>) 60222989816SDimitry Andric llvm::Function *LifetimeEndFn = nullptr; 603809500fcSDimitry Andric 60406d4ba38SDimitry Andric std::unique_ptr<SanitizerMetadata> SanitizerMD; 605809500fcSDimitry Andric 606461a67faSDimitry Andric llvm::MapVector<const Decl *, bool> DeferredEmptyCoverageMappingDecls; 60706d4ba38SDimitry Andric 60806d4ba38SDimitry Andric std::unique_ptr<CoverageMappingModuleGen> CoverageMapping; 60945b53394SDimitry Andric 61045b53394SDimitry Andric /// Mapping from canonical types to their metadata identifiers. We need to 61145b53394SDimitry Andric /// maintain this mapping because identifiers may be formed from distinct 61245b53394SDimitry Andric /// MDNodes. 613461a67faSDimitry Andric typedef llvm::DenseMap<QualType, llvm::Metadata *> MetadataTypeMap; 614461a67faSDimitry Andric MetadataTypeMap MetadataIdMap; 61548675466SDimitry Andric MetadataTypeMap VirtualMetadataIdMap; 616461a67faSDimitry Andric MetadataTypeMap GeneralizedMetadataIdMap; 61745b53394SDimitry Andric 618e3b55780SDimitry Andric // Helps squashing blocks of TopLevelStmtDecl into a single llvm::Function 619e3b55780SDimitry Andric // when used with -fincremental-extensions. 620e3b55780SDimitry Andric std::pair<std::unique_ptr<CodeGenFunction>, const TopLevelStmtDecl *> 621e3b55780SDimitry Andric GlobalTopLevelStmtBlockInFlight; 622e3b55780SDimitry Andric 623ac9a064cSDimitry Andric llvm::DenseMap<GlobalDecl, uint16_t> PtrAuthDiscriminatorHashes; 624ac9a064cSDimitry Andric 625ac9a064cSDimitry Andric llvm::DenseMap<const CXXRecordDecl *, std::optional<PointerAuthQualifier>> 626ac9a064cSDimitry Andric VTablePtrAuthInfos; 627ac9a064cSDimitry Andric std::optional<PointerAuthQualifier> 628ac9a064cSDimitry Andric computeVTPointerAuthentication(const CXXRecordDecl *ThisClass); 629ac9a064cSDimitry Andric 630ec2b103cSEd Schouten public: 63108e8dd7bSDimitry Andric CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, 63208e8dd7bSDimitry Andric const HeaderSearchOptions &headersearchopts, 633c192b3dcSDimitry Andric const PreprocessorOptions &ppopts, 63445b53394SDimitry Andric const CodeGenOptions &CodeGenOpts, llvm::Module &M, 63506d4ba38SDimitry Andric DiagnosticsEngine &Diags, 63606d4ba38SDimitry Andric CoverageSourceInfo *CoverageInfo = nullptr); 637ec2b103cSEd Schouten 638ec2b103cSEd Schouten ~CodeGenModule(); 639ec2b103cSEd Schouten 6409f4dbff6SDimitry Andric void clear(); 6419f4dbff6SDimitry Andric 6429f4dbff6SDimitry Andric /// Finalize LLVM code generation. 643ec2b103cSEd Schouten void Release(); 644ec2b103cSEd Schouten 645461a67faSDimitry Andric /// Return true if we should emit location information for expressions. 646461a67faSDimitry Andric bool getExpressionLocationsEnabled() const; 647461a67faSDimitry Andric 6489f4dbff6SDimitry Andric /// Return a reference to the configured Objective-C runtime. getObjCRuntime()649ec2b103cSEd Schouten CGObjCRuntime &getObjCRuntime() { 65036981b17SDimitry Andric if (!ObjCRuntime) createObjCRuntime(); 65136981b17SDimitry Andric return *ObjCRuntime; 652ec2b103cSEd Schouten } 653ec2b103cSEd Schouten 6549f4dbff6SDimitry Andric /// Return true iff an Objective-C runtime has been configured. hasObjCRuntime()65536981b17SDimitry Andric bool hasObjCRuntime() { return !!ObjCRuntime; } 65636981b17SDimitry Andric getModuleNameHash()657344a3780SDimitry Andric const std::string &getModuleNameHash() const { return ModuleNameHash; } 658344a3780SDimitry Andric 6599f4dbff6SDimitry Andric /// Return a reference to the configured OpenCL runtime. getOpenCLRuntime()66036981b17SDimitry Andric CGOpenCLRuntime &getOpenCLRuntime() { 6619f4dbff6SDimitry Andric assert(OpenCLRuntime != nullptr); 66236981b17SDimitry Andric return *OpenCLRuntime; 66336981b17SDimitry Andric } 66436981b17SDimitry Andric 6659f4dbff6SDimitry Andric /// Return a reference to the configured OpenMP runtime. getOpenMPRuntime()6669f4dbff6SDimitry Andric CGOpenMPRuntime &getOpenMPRuntime() { 6679f4dbff6SDimitry Andric assert(OpenMPRuntime != nullptr); 6689f4dbff6SDimitry Andric return *OpenMPRuntime; 6699f4dbff6SDimitry Andric } 6709f4dbff6SDimitry Andric 6719f4dbff6SDimitry Andric /// Return a reference to the configured CUDA runtime. getCUDARuntime()67236981b17SDimitry Andric CGCUDARuntime &getCUDARuntime() { 6739f4dbff6SDimitry Andric assert(CUDARuntime != nullptr); 67436981b17SDimitry Andric return *CUDARuntime; 67536981b17SDimitry Andric } 676ec2b103cSEd Schouten 677145449b1SDimitry Andric /// Return a reference to the configured HLSL runtime. getHLSLRuntime()678145449b1SDimitry Andric CGHLSLRuntime &getHLSLRuntime() { 679145449b1SDimitry Andric assert(HLSLRuntime != nullptr); 680145449b1SDimitry Andric return *HLSLRuntime; 681145449b1SDimitry Andric } 682145449b1SDimitry Andric getObjCEntrypoints()68345b53394SDimitry Andric ObjCEntrypoints &getObjCEntrypoints() const { 68445b53394SDimitry Andric assert(ObjCData != nullptr); 68545b53394SDimitry Andric return *ObjCData; 686180abc3dSDimitry Andric } 687180abc3dSDimitry Andric 688b60736ecSDimitry Andric // Version checking functions, used to implement ObjC's @available: 6897442d6faSDimitry Andric // i32 @__isOSVersionAtLeast(i32, i32, i32) 69022989816SDimitry Andric llvm::FunctionCallee IsOSVersionAtLeastFn = nullptr; 691b60736ecSDimitry Andric // i32 @__isPlatformVersionAtLeast(i32, i32, i32, i32) 692b60736ecSDimitry Andric llvm::FunctionCallee IsPlatformVersionAtLeastFn = nullptr; 6937442d6faSDimitry Andric getPGOStats()6949f4dbff6SDimitry Andric InstrProfStats &getPGOStats() { return PGOStats; } getPGOReader()6959f4dbff6SDimitry Andric llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); } 6969f4dbff6SDimitry Andric getCoverageMapping()69706d4ba38SDimitry Andric CoverageMappingModuleGen *getCoverageMapping() const { 69806d4ba38SDimitry Andric return CoverageMapping.get(); 69906d4ba38SDimitry Andric } 70006d4ba38SDimitry Andric getStaticLocalDeclAddress(const VarDecl * D)701dbe13110SDimitry Andric llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) { 702dbe13110SDimitry Andric return StaticLocalDeclMap[D]; 7030883ccd9SRoman Divacky } setStaticLocalDeclAddress(const VarDecl * D,llvm::Constant * C)7040883ccd9SRoman Divacky void setStaticLocalDeclAddress(const VarDecl *D, 705dbe13110SDimitry Andric llvm::Constant *C) { 706dbe13110SDimitry Andric StaticLocalDeclMap[D] = C; 707dbe13110SDimitry Andric } 708dbe13110SDimitry Andric 70906d4ba38SDimitry Andric llvm::Constant * 71006d4ba38SDimitry Andric getOrCreateStaticVarDecl(const VarDecl &D, 71106d4ba38SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage); 71206d4ba38SDimitry Andric getStaticLocalDeclGuardAddress(const VarDecl * D)713dbe13110SDimitry Andric llvm::GlobalVariable *getStaticLocalDeclGuardAddress(const VarDecl *D) { 714dbe13110SDimitry Andric return StaticLocalDeclGuardMap[D]; 715dbe13110SDimitry Andric } setStaticLocalDeclGuardAddress(const VarDecl * D,llvm::GlobalVariable * C)716dbe13110SDimitry Andric void setStaticLocalDeclGuardAddress(const VarDecl *D, 717dbe13110SDimitry Andric llvm::GlobalVariable *C) { 718dbe13110SDimitry Andric StaticLocalDeclGuardMap[D] = C; 719dbe13110SDimitry Andric } 720dbe13110SDimitry Andric 72122989816SDimitry Andric Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant, 72222989816SDimitry Andric CharUnits Align); 72322989816SDimitry Andric 7249f4dbff6SDimitry Andric bool lookupRepresentativeDecl(StringRef MangledName, 7259f4dbff6SDimitry Andric GlobalDecl &Result) const; 7269f4dbff6SDimitry Andric getAtomicSetterHelperFnMap(QualType Ty)727dbe13110SDimitry Andric llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) { 728dbe13110SDimitry Andric return AtomicSetterHelperFnMap[Ty]; 729dbe13110SDimitry Andric } setAtomicSetterHelperFnMap(QualType Ty,llvm::Constant * Fn)730dbe13110SDimitry Andric void setAtomicSetterHelperFnMap(QualType Ty, 731dbe13110SDimitry Andric llvm::Constant *Fn) { 732dbe13110SDimitry Andric AtomicSetterHelperFnMap[Ty] = Fn; 733dbe13110SDimitry Andric } 734dbe13110SDimitry Andric getAtomicGetterHelperFnMap(QualType Ty)735dbe13110SDimitry Andric llvm::Constant *getAtomicGetterHelperFnMap(QualType Ty) { 736dbe13110SDimitry Andric return AtomicGetterHelperFnMap[Ty]; 737dbe13110SDimitry Andric } setAtomicGetterHelperFnMap(QualType Ty,llvm::Constant * Fn)738dbe13110SDimitry Andric void setAtomicGetterHelperFnMap(QualType Ty, 739dbe13110SDimitry Andric llvm::Constant *Fn) { 740dbe13110SDimitry Andric AtomicGetterHelperFnMap[Ty] = Fn; 7410883ccd9SRoman Divacky } 7420883ccd9SRoman Divacky getTypeDescriptorFromMap(QualType Ty)7439f4dbff6SDimitry Andric llvm::Constant *getTypeDescriptorFromMap(QualType Ty) { 744bfef3995SDimitry Andric return TypeDescriptorMap[Ty]; 745bfef3995SDimitry Andric } setTypeDescriptorInMap(QualType Ty,llvm::Constant * C)7469f4dbff6SDimitry Andric void setTypeDescriptorInMap(QualType Ty, llvm::Constant *C) { 747bfef3995SDimitry Andric TypeDescriptorMap[Ty] = C; 748bfef3995SDimitry Andric } 749bfef3995SDimitry Andric getModuleDebugInfo()7502b6b257fSDimitry Andric CGDebugInfo *getModuleDebugInfo() { return DebugInfo.get(); } 75101af97d3SDimitry Andric getNoObjCARCExceptionsMetadata()752dbe13110SDimitry Andric llvm::MDNode *getNoObjCARCExceptionsMetadata() { 753dbe13110SDimitry Andric if (!NoObjCARCExceptionsMetadata) 754e3b55780SDimitry Andric NoObjCARCExceptionsMetadata = 755e3b55780SDimitry Andric llvm::MDNode::get(getLLVMContext(), std::nullopt); 756dbe13110SDimitry Andric return NoObjCARCExceptionsMetadata; 757dbe13110SDimitry Andric } 758dbe13110SDimitry Andric getContext()759ec2b103cSEd Schouten ASTContext &getContext() const { return Context; } getLangOpts()760dbe13110SDimitry Andric const LangOptions &getLangOpts() const { return LangOpts; } getFileSystem()76108e8dd7bSDimitry Andric const IntrusiveRefCntPtr<llvm::vfs::FileSystem> &getFileSystem() const { 76208e8dd7bSDimitry Andric return FS; 76308e8dd7bSDimitry Andric } getHeaderSearchOpts()764c192b3dcSDimitry Andric const HeaderSearchOptions &getHeaderSearchOpts() 765c192b3dcSDimitry Andric const { return HeaderSearchOpts; } getPreprocessorOpts()766c192b3dcSDimitry Andric const PreprocessorOptions &getPreprocessorOpts() 767c192b3dcSDimitry Andric const { return PreprocessorOpts; } getCodeGenOpts()7686a037251SDimitry Andric const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; } getModule()769ec2b103cSEd Schouten llvm::Module &getModule() const { return TheModule; } getDiags()77036981b17SDimitry Andric DiagnosticsEngine &getDiags() const { return Diags; } getDataLayout()77145b53394SDimitry Andric const llvm::DataLayout &getDataLayout() const { 77245b53394SDimitry Andric return TheModule.getDataLayout(); 77345b53394SDimitry Andric } getTarget()7746a037251SDimitry Andric const TargetInfo &getTarget() const { return Target; } getTriple()775bab175ecSDimitry Andric const llvm::Triple &getTriple() const { return Target.getTriple(); } 77606d4ba38SDimitry Andric bool supportsCOMDAT() const; 7775e20cdd8SDimitry Andric void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO); 77806d4ba38SDimitry Andric 779e6b73279SDimitry Andric const ABIInfo &getABIInfo(); getCXXABI()7809f4dbff6SDimitry Andric CGCXXABI &getCXXABI() const { return *ABI; } getLLVMContext()7814c8b2481SRoman Divacky llvm::LLVMContext &getLLVMContext() { return VMContext; } 782ec2b103cSEd Schouten shouldUseTBAA()7839f4dbff6SDimitry Andric bool shouldUseTBAA() const { return TBAA != nullptr; } 784c3b054d2SDimitry Andric 7856a037251SDimitry Andric const TargetCodeGenInfo &getTargetCodeGenInfo(); 7866a037251SDimitry Andric getTypes()787e6b73279SDimitry Andric CodeGenTypes &getTypes() { return *Types; } 7886a037251SDimitry Andric getVTables()7896a037251SDimitry Andric CodeGenVTables &getVTables() { return VTables; } 790bfef3995SDimitry Andric getItaniumVTableContext()791bfef3995SDimitry Andric ItaniumVTableContext &getItaniumVTableContext() { 792bfef3995SDimitry Andric return VTables.getItaniumVTableContext(); 793bfef3995SDimitry Andric } 794bfef3995SDimitry Andric getItaniumVTableContext()795e3b55780SDimitry Andric const ItaniumVTableContext &getItaniumVTableContext() const { 796e3b55780SDimitry Andric return VTables.getItaniumVTableContext(); 797e3b55780SDimitry Andric } 798e3b55780SDimitry Andric getMicrosoftVTableContext()799bfef3995SDimitry Andric MicrosoftVTableContext &getMicrosoftVTableContext() { 800bfef3995SDimitry Andric return VTables.getMicrosoftVTableContext(); 801bfef3995SDimitry Andric } 8026a037251SDimitry Andric getGlobalCtors()80306d4ba38SDimitry Andric CtorList &getGlobalCtors() { return GlobalCtors; } getGlobalDtors()80406d4ba38SDimitry Andric CtorList &getGlobalDtors() { return GlobalDtors; } 80506d4ba38SDimitry Andric 806461a67faSDimitry Andric /// getTBAATypeInfo - Get metadata used to describe accesses to objects of 807461a67faSDimitry Andric /// the given type. 808461a67faSDimitry Andric llvm::MDNode *getTBAATypeInfo(QualType QTy); 809461a67faSDimitry Andric 810461a67faSDimitry Andric /// getTBAAAccessInfo - Get TBAA information that describes an access to 811461a67faSDimitry Andric /// an object of the given type. 812461a67faSDimitry Andric TBAAAccessInfo getTBAAAccessInfo(QualType AccessType); 813461a67faSDimitry Andric 814461a67faSDimitry Andric /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an 815461a67faSDimitry Andric /// access to a virtual table pointer. 816461a67faSDimitry Andric TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType); 817461a67faSDimitry Andric 81813cc256eSDimitry Andric llvm::MDNode *getTBAAStructInfo(QualType QTy); 819461a67faSDimitry Andric 820461a67faSDimitry Andric /// getTBAABaseTypeInfo - Get metadata that describes the given base access 821461a67faSDimitry Andric /// type. Return null if the type is not suitable for use in TBAA access tags. 822461a67faSDimitry Andric llvm::MDNode *getTBAABaseTypeInfo(QualType QTy); 823461a67faSDimitry Andric 824461a67faSDimitry Andric /// getTBAAAccessTagInfo - Get TBAA tag for a given memory access. 825461a67faSDimitry Andric llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info); 826461a67faSDimitry Andric 827461a67faSDimitry Andric /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of 828461a67faSDimitry Andric /// type casts. 829461a67faSDimitry Andric TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, 830461a67faSDimitry Andric TBAAAccessInfo TargetInfo); 831461a67faSDimitry Andric 832461a67faSDimitry Andric /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the 833461a67faSDimitry Andric /// purposes of conditional operator. 834461a67faSDimitry Andric TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, 835461a67faSDimitry Andric TBAAAccessInfo InfoB); 836461a67faSDimitry Andric 83748675466SDimitry Andric /// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the 83848675466SDimitry Andric /// purposes of memory transfer calls. 83948675466SDimitry Andric TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, 84048675466SDimitry Andric TBAAAccessInfo SrcInfo); 84148675466SDimitry Andric 842461a67faSDimitry Andric /// getTBAAInfoForSubobject - Get TBAA information for an access with a given 843461a67faSDimitry Andric /// base lvalue. getTBAAInfoForSubobject(LValue Base,QualType AccessType)844461a67faSDimitry Andric TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType) { 845461a67faSDimitry Andric if (Base.getTBAAInfo().isMayAlias()) 846461a67faSDimitry Andric return TBAAAccessInfo::getMayAliasInfo(); 847461a67faSDimitry Andric return getTBAAAccessInfo(AccessType); 848461a67faSDimitry Andric } 849dbe13110SDimitry Andric 850809500fcSDimitry Andric bool isPaddedAtomicType(QualType type); 851809500fcSDimitry Andric bool isPaddedAtomicType(const AtomicType *type); 852809500fcSDimitry Andric 853461a67faSDimitry Andric /// DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag. 85445b53394SDimitry Andric void DecorateInstructionWithTBAA(llvm::Instruction *Inst, 855461a67faSDimitry Andric TBAAAccessInfo TBAAInfo); 856ec2b103cSEd Schouten 85745b53394SDimitry Andric /// Adds !invariant.barrier !tag to instruction 85845b53394SDimitry Andric void DecorateInstructionWithInvariantGroup(llvm::Instruction *I, 85945b53394SDimitry Andric const CXXRecordDecl *RD); 86045b53394SDimitry Andric 8619f4dbff6SDimitry Andric /// Emit the given number of characters as a value of type size_t. 862180abc3dSDimitry Andric llvm::ConstantInt *getSize(CharUnits numChars); 863180abc3dSDimitry Andric 8649f4dbff6SDimitry Andric /// Set the visibility for the given LLVM GlobalValue. 86548675466SDimitry Andric void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const; 86648675466SDimitry Andric 86748675466SDimitry Andric void setDSOLocal(llvm::GlobalValue *GV) const; 86848675466SDimitry Andric shouldMapVisibilityToDLLExport(const NamedDecl * D)869145449b1SDimitry Andric bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const { 870145449b1SDimitry Andric return getLangOpts().hasDefaultVisibilityExportMapping() && D && 871145449b1SDimitry Andric (D->getLinkageAndVisibility().getVisibility() == 872145449b1SDimitry Andric DefaultVisibility) && 873145449b1SDimitry Andric (getLangOpts().isAllDefaultVisibilityExportMapping() || 874145449b1SDimitry Andric (getLangOpts().isExplicitDefaultVisibilityExportMapping() && 875145449b1SDimitry Andric D->getLinkageAndVisibility().isVisibilityExplicit())); 876145449b1SDimitry Andric } 87748675466SDimitry Andric void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const; 87848675466SDimitry Andric void setDLLImportDLLExport(llvm::GlobalValue *GV, const NamedDecl *D) const; 87948675466SDimitry Andric /// Set visibility, dllimport/dllexport and dso_local. 88048675466SDimitry Andric /// This must be called after dllimport/dllexport is set. 88148675466SDimitry Andric void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const; 88248675466SDimitry Andric void setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D) const; 883bca07a45SDimitry Andric 88422989816SDimitry Andric void setGVPropertiesAux(llvm::GlobalValue *GV, const NamedDecl *D) const; 88522989816SDimitry Andric 88606d4ba38SDimitry Andric /// Set the TLS mode for the given LLVM GlobalValue for the thread-local 8879f4dbff6SDimitry Andric /// variable declaration D. 88806d4ba38SDimitry Andric void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const; 88956d91b49SDimitry Andric 890cfca06d7SDimitry Andric /// Get LLVM TLS mode from CodeGenOptions. 891cfca06d7SDimitry Andric llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const; 892cfca06d7SDimitry Andric GetLLVMVisibility(Visibility V)893bca07a45SDimitry Andric static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) { 894bca07a45SDimitry Andric switch (V) { 895bca07a45SDimitry Andric case DefaultVisibility: return llvm::GlobalValue::DefaultVisibility; 896bca07a45SDimitry Andric case HiddenVisibility: return llvm::GlobalValue::HiddenVisibility; 897bca07a45SDimitry Andric case ProtectedVisibility: return llvm::GlobalValue::ProtectedVisibility; 898bca07a45SDimitry Andric } 899bca07a45SDimitry Andric llvm_unreachable("unknown visibility!"); 900bca07a45SDimitry Andric } 9013d1dcd9bSDimitry Andric 902bab175ecSDimitry Andric llvm::Constant *GetAddrOfGlobal(GlobalDecl GD, 903bab175ecSDimitry Andric ForDefinition_t IsForDefinition 904bab175ecSDimitry Andric = NotForDefinition); 90579ade4e0SRoman Divacky 9069f4dbff6SDimitry Andric /// Will return a global variable of the given type. If a variable with a 9079f4dbff6SDimitry Andric /// different type already exists then a new variable with the right type 9089f4dbff6SDimitry Andric /// will be created and all uses of the old variable will be replaced with a 9099f4dbff6SDimitry Andric /// bitcast to the new variable. 910bca07a45SDimitry Andric llvm::GlobalVariable * 91136981b17SDimitry Andric CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, 912676fbe81SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage, 913e3b55780SDimitry Andric llvm::Align Alignment); 914bca07a45SDimitry Andric 915cfca06d7SDimitry Andric llvm::Function *CreateGlobalInitOrCleanUpFunction( 916cfca06d7SDimitry Andric llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, 917145449b1SDimitry Andric SourceLocation Loc = SourceLocation(), bool TLS = false, 918145449b1SDimitry Andric llvm::GlobalVariable::LinkageTypes Linkage = 919145449b1SDimitry Andric llvm::GlobalVariable::InternalLinkage); 92006d4ba38SDimitry Andric 9218746d127SDimitry Andric /// Return the AST address space of the underlying global variable for D, as 9229f4dbff6SDimitry Andric /// determined by its declaration. Normally this is the same as the address 9239f4dbff6SDimitry Andric /// space of D's type, but in CUDA, address spaces are associated with 9248746d127SDimitry Andric /// declarations, not types. If D is nullptr, return the default address 9258746d127SDimitry Andric /// space for global variable. 9268746d127SDimitry Andric /// 9278746d127SDimitry Andric /// For languages without explicit address spaces, if D has default address 9288746d127SDimitry Andric /// space, target-specific global or constant address space may be returned. 929461a67faSDimitry Andric LangAS GetGlobalVarAddressSpace(const VarDecl *D); 93056d91b49SDimitry Andric 931344a3780SDimitry Andric /// Return the AST address space of constant literal, which is used to emit 932344a3780SDimitry Andric /// the constant literal as global variable in LLVM IR. 933344a3780SDimitry Andric /// Note: This is not necessarily the address space of the constant literal 934344a3780SDimitry Andric /// in AST. For address space agnostic language, e.g. C++, constant literal 935344a3780SDimitry Andric /// in AST is always in default address space. 936344a3780SDimitry Andric LangAS GetGlobalConstantAddressSpace() const; 937344a3780SDimitry Andric 9389f4dbff6SDimitry Andric /// Return the llvm::Constant for the address of the given global variable. 9392b6b257fSDimitry Andric /// If Ty is non-null and if the global doesn't exist, then it will be created 9409f4dbff6SDimitry Andric /// with the specified type instead of whatever the normal requested type 94148675466SDimitry Andric /// would be. If IsForDefinition is true, it is guaranteed that an actual 9422b6b257fSDimitry Andric /// global with type Ty will be returned, not conversion of a variable with 9432b6b257fSDimitry Andric /// the same mangled name but some other type. 944ec2b103cSEd Schouten llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D, 9452b6b257fSDimitry Andric llvm::Type *Ty = nullptr, 946bab175ecSDimitry Andric ForDefinition_t IsForDefinition 947bab175ecSDimitry Andric = NotForDefinition); 948ec2b103cSEd Schouten 9499f4dbff6SDimitry Andric /// Return the address of the given function. If Ty is non-null, then this 9509f4dbff6SDimitry Andric /// function will use the specified type if it has to create it. 95145b53394SDimitry Andric llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = nullptr, 9529f4dbff6SDimitry Andric bool ForVTable = false, 95345b53394SDimitry Andric bool DontDefer = false, 954bab175ecSDimitry Andric ForDefinition_t IsForDefinition 955bab175ecSDimitry Andric = NotForDefinition); 95601af97d3SDimitry Andric 95777fc4c14SDimitry Andric // Return the function body address of the given function. 95877fc4c14SDimitry Andric llvm::Constant *GetFunctionStart(const ValueDecl *Decl); 95977fc4c14SDimitry Andric 960ac9a064cSDimitry Andric /// Return a function pointer for a reference to the given function. 961ac9a064cSDimitry Andric /// This correctly handles weak references, but does not apply a 962ac9a064cSDimitry Andric /// pointer signature. 963ac9a064cSDimitry Andric llvm::Constant *getRawFunctionPointer(GlobalDecl GD, 964ac9a064cSDimitry Andric llvm::Type *Ty = nullptr); 965ac9a064cSDimitry Andric 966ac9a064cSDimitry Andric /// Return the ABI-correct function pointer value for a reference 967ac9a064cSDimitry Andric /// to the given function. This will apply a pointer signature if 968ac9a064cSDimitry Andric /// necessary, caching the result for the given function. 969ac9a064cSDimitry Andric llvm::Constant *getFunctionPointer(GlobalDecl GD, llvm::Type *Ty = nullptr); 970ac9a064cSDimitry Andric 971ac9a064cSDimitry Andric /// Return the ABI-correct function pointer value for a reference 972ac9a064cSDimitry Andric /// to the given function. This will apply a pointer signature if 973ac9a064cSDimitry Andric /// necessary. 974ac9a064cSDimitry Andric llvm::Constant *getFunctionPointer(llvm::Constant *Pointer, 975ac9a064cSDimitry Andric QualType FunctionType); 976ac9a064cSDimitry Andric 977ac9a064cSDimitry Andric llvm::Constant *getMemberFunctionPointer(const FunctionDecl *FD, 978ac9a064cSDimitry Andric llvm::Type *Ty = nullptr); 979ac9a064cSDimitry Andric 980ac9a064cSDimitry Andric llvm::Constant *getMemberFunctionPointer(llvm::Constant *Pointer, 981ac9a064cSDimitry Andric QualType FT); 982ac9a064cSDimitry Andric 983ac9a064cSDimitry Andric CGPointerAuthInfo getFunctionPointerAuthInfo(QualType T); 984ac9a064cSDimitry Andric 985ac9a064cSDimitry Andric CGPointerAuthInfo getMemberFunctionPointerAuthInfo(QualType FT); 986ac9a064cSDimitry Andric 987ac9a064cSDimitry Andric CGPointerAuthInfo getPointerAuthInfoForPointeeType(QualType type); 988ac9a064cSDimitry Andric 989ac9a064cSDimitry Andric CGPointerAuthInfo getPointerAuthInfoForType(QualType type); 990ac9a064cSDimitry Andric 991ac9a064cSDimitry Andric bool shouldSignPointer(const PointerAuthSchema &Schema); 992ac9a064cSDimitry Andric llvm::Constant *getConstantSignedPointer(llvm::Constant *Pointer, 993ac9a064cSDimitry Andric const PointerAuthSchema &Schema, 994ac9a064cSDimitry Andric llvm::Constant *StorageAddress, 995ac9a064cSDimitry Andric GlobalDecl SchemaDecl, 996ac9a064cSDimitry Andric QualType SchemaType); 997ac9a064cSDimitry Andric 998ac9a064cSDimitry Andric llvm::Constant * 999ac9a064cSDimitry Andric getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key, 1000ac9a064cSDimitry Andric llvm::Constant *StorageAddress, 1001ac9a064cSDimitry Andric llvm::ConstantInt *OtherDiscriminator); 1002ac9a064cSDimitry Andric 1003ac9a064cSDimitry Andric llvm::ConstantInt * 1004ac9a064cSDimitry Andric getPointerAuthOtherDiscriminator(const PointerAuthSchema &Schema, 1005ac9a064cSDimitry Andric GlobalDecl SchemaDecl, QualType SchemaType); 1006ac9a064cSDimitry Andric 1007ac9a064cSDimitry Andric uint16_t getPointerAuthDeclDiscriminator(GlobalDecl GD); 1008ac9a064cSDimitry Andric std::optional<CGPointerAuthInfo> 1009ac9a064cSDimitry Andric getVTablePointerAuthInfo(CodeGenFunction *Context, 1010ac9a064cSDimitry Andric const CXXRecordDecl *Record, 1011ac9a064cSDimitry Andric llvm::Value *StorageAddress); 1012ac9a064cSDimitry Andric 1013ac9a064cSDimitry Andric std::optional<PointerAuthQualifier> 1014ac9a064cSDimitry Andric getVTablePointerAuthentication(const CXXRecordDecl *thisClass); 1015ac9a064cSDimitry Andric 1016ac9a064cSDimitry Andric CGPointerAuthInfo EmitPointerAuthInfo(const RecordDecl *RD); 1017ac9a064cSDimitry Andric 10187fa27ce4SDimitry Andric // Return whether RTTI information should be emitted for this target. 10197fa27ce4SDimitry Andric bool shouldEmitRTTI(bool ForEH = false) { 10207fa27ce4SDimitry Andric return (ForEH || getLangOpts().RTTI) && !getLangOpts().CUDAIsDevice && 10217fa27ce4SDimitry Andric !(getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice && 1022ac9a064cSDimitry Andric (getTriple().isNVPTX() || getTriple().isAMDGPU())); 10237fa27ce4SDimitry Andric } 10247fa27ce4SDimitry Andric 10259f4dbff6SDimitry Andric /// Get the address of the RTTI descriptor for the given type. 10260883ccd9SRoman Divacky llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false); 102734d02d0bSRoman Divacky 1028cfca06d7SDimitry Andric /// Get the address of a GUID. 1029cfca06d7SDimitry Andric ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD); 103013cc256eSDimitry Andric 1031145449b1SDimitry Andric /// Get the address of a UnnamedGlobalConstant 1032145449b1SDimitry Andric ConstantAddress 1033145449b1SDimitry Andric GetAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *GCD); 1034145449b1SDimitry Andric 1035b60736ecSDimitry Andric /// Get the address of a template parameter object. 1036b60736ecSDimitry Andric ConstantAddress 1037b60736ecSDimitry Andric GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO); 1038b60736ecSDimitry Andric 10399f4dbff6SDimitry Andric /// Get the address of the thunk for the given global decl. 104048675466SDimitry Andric llvm::Constant *GetAddrOfThunk(StringRef Name, llvm::Type *FnTy, 104148675466SDimitry Andric GlobalDecl GD); 10424c8b2481SRoman Divacky 10439f4dbff6SDimitry Andric /// Get a reference to the target of VD. 104445b53394SDimitry Andric ConstantAddress GetWeakRefReference(const ValueDecl *VD); 104545b53394SDimitry Andric 104645b53394SDimitry Andric /// Returns the assumed alignment of an opaque pointer to the given class. 104745b53394SDimitry Andric CharUnits getClassPointerAlignment(const CXXRecordDecl *CD); 104845b53394SDimitry Andric 1049cfca06d7SDimitry Andric /// Returns the minimum object size for an object of the given class type 1050cfca06d7SDimitry Andric /// (or a class derived from it). 1051cfca06d7SDimitry Andric CharUnits getMinimumClassObjectSize(const CXXRecordDecl *CD); 1052cfca06d7SDimitry Andric 1053cfca06d7SDimitry Andric /// Returns the minimum object size for an object of the given type. getMinimumObjectSize(QualType Ty)1054cfca06d7SDimitry Andric CharUnits getMinimumObjectSize(QualType Ty) { 1055cfca06d7SDimitry Andric if (CXXRecordDecl *RD = Ty->getAsCXXRecordDecl()) 1056cfca06d7SDimitry Andric return getMinimumClassObjectSize(RD); 1057cfca06d7SDimitry Andric return getContext().getTypeSizeInChars(Ty); 1058cfca06d7SDimitry Andric } 1059cfca06d7SDimitry Andric 106045b53394SDimitry Andric /// Returns the assumed alignment of a virtual base of a class. 106145b53394SDimitry Andric CharUnits getVBaseAlignment(CharUnits DerivedAlign, 106245b53394SDimitry Andric const CXXRecordDecl *Derived, 106345b53394SDimitry Andric const CXXRecordDecl *VBase); 106445b53394SDimitry Andric 106545b53394SDimitry Andric /// Given a class pointer with an actual known alignment, and the 106645b53394SDimitry Andric /// expected alignment of an object at a dynamic offset w.r.t that 106745b53394SDimitry Andric /// pointer, return the alignment to assume at the offset. 106845b53394SDimitry Andric CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, 106945b53394SDimitry Andric const CXXRecordDecl *Class, 107045b53394SDimitry Andric CharUnits ExpectedTargetAlign); 1071dd5132ceSRoman Divacky 1072c192b3dcSDimitry Andric CharUnits 1073c192b3dcSDimitry Andric computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, 1074c192b3dcSDimitry Andric CastExpr::path_const_iterator Start, 1075c192b3dcSDimitry Andric CastExpr::path_const_iterator End); 1076c192b3dcSDimitry Andric 10779f4dbff6SDimitry Andric /// Returns the offset from a derived class to a class. Returns null if the 10789f4dbff6SDimitry Andric /// offset is 0. 1079ecb7e5c8SRoman Divacky llvm::Constant * 1080ecb7e5c8SRoman Divacky GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 10813d1dcd9bSDimitry Andric CastExpr::path_const_iterator PathBegin, 10823d1dcd9bSDimitry Andric CastExpr::path_const_iterator PathEnd); 10834c8b2481SRoman Divacky 108445b53394SDimitry Andric llvm::FoldingSet<BlockByrefHelpers> ByrefHelpersCache; 1085bca07a45SDimitry Andric 10869f4dbff6SDimitry Andric /// Fetches the global unique block count. getUniqueBlockCount()1087c3b054d2SDimitry Andric int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; } 1088bca07a45SDimitry Andric 10899f4dbff6SDimitry Andric /// Fetches the type of a generic block descriptor. 1090180abc3dSDimitry Andric llvm::Type *getBlockDescriptorType(); 1091bca07a45SDimitry Andric 10929f4dbff6SDimitry Andric /// The type of a generic block literal. 1093180abc3dSDimitry Andric llvm::Type *getGenericBlockLiteralType(); 1094bca07a45SDimitry Andric 10959f4dbff6SDimitry Andric /// Gets the address of a block which requires no captures. 1096bab175ecSDimitry Andric llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name); 1097bab175ecSDimitry Andric 1098bab175ecSDimitry Andric /// Returns the address of a block which requires no caputres, or null if 1099bab175ecSDimitry Andric /// we've yet to emit the block for BE. getAddrOfGlobalBlockIfEmitted(const BlockExpr * BE)1100bab175ecSDimitry Andric llvm::Constant *getAddrOfGlobalBlockIfEmitted(const BlockExpr *BE) { 1101bab175ecSDimitry Andric return EmittedGlobalBlocks.lookup(BE); 1102bab175ecSDimitry Andric } 1103bab175ecSDimitry Andric 1104bab175ecSDimitry Andric /// Notes that BE's global block is available via Addr. Asserts that BE 1105bab175ecSDimitry Andric /// isn't already emitted. 1106bab175ecSDimitry Andric void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr); 1107bca07a45SDimitry Andric 11089f4dbff6SDimitry Andric /// Return a pointer to a constant CFString object for the given string. 110945b53394SDimitry Andric ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal); 1110ec2b103cSEd Schouten 11119f4dbff6SDimitry Andric /// Return a constant array for the given string. 1112dbe13110SDimitry Andric llvm::Constant *GetConstantArrayFromStringLiteral(const StringLiteral *E); 1113dbe13110SDimitry Andric 11149f4dbff6SDimitry Andric /// Return a pointer to a constant array for the given string literal. 111545b53394SDimitry Andric ConstantAddress 111606d4ba38SDimitry Andric GetAddrOfConstantStringFromLiteral(const StringLiteral *S, 111706d4ba38SDimitry Andric StringRef Name = ".str"); 1118ec2b103cSEd Schouten 11199f4dbff6SDimitry Andric /// Return a pointer to a constant array for the given ObjCEncodeExpr node. 112045b53394SDimitry Andric ConstantAddress 11219f4dbff6SDimitry Andric GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *); 1122ec2b103cSEd Schouten 11239f4dbff6SDimitry Andric /// Returns a pointer to a character array containing the literal and a 11249f4dbff6SDimitry Andric /// terminating '\0' character. The result has pointer to array type. 1125ec2b103cSEd Schouten /// 1126ec2b103cSEd Schouten /// \param GlobalName If provided, the name to use for the global (if one is 1127ec2b103cSEd Schouten /// created). 112845b53394SDimitry Andric ConstantAddress 11299f4dbff6SDimitry Andric GetAddrOfConstantCString(const std::string &Str, 113045b53394SDimitry Andric const char *GlobalName = nullptr); 113136981b17SDimitry Andric 11329f4dbff6SDimitry Andric /// Returns a pointer to a constant global variable for the given file-scope 11339f4dbff6SDimitry Andric /// compound literal expression. 113445b53394SDimitry Andric ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E); 1135dbe13110SDimitry Andric 1136bab175ecSDimitry Andric /// If it's been emitted already, returns the GlobalVariable corresponding to 1137bab175ecSDimitry Andric /// a compound literal. Otherwise, returns null. 1138bab175ecSDimitry Andric llvm::GlobalVariable * 1139bab175ecSDimitry Andric getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E); 1140bab175ecSDimitry Andric 1141bab175ecSDimitry Andric /// Notes that CLE's GlobalVariable is GV. Asserts that CLE isn't already 1142bab175ecSDimitry Andric /// emitted. 1143bab175ecSDimitry Andric void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE, 1144bab175ecSDimitry Andric llvm::GlobalVariable *GV); 1145bab175ecSDimitry Andric 114648675466SDimitry Andric /// Returns a pointer to a global variable representing a temporary 1147bfef3995SDimitry Andric /// with static or thread storage duration. 114845b53394SDimitry Andric ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, 1149bfef3995SDimitry Andric const Expr *Inner); 1150bfef3995SDimitry Andric 115148675466SDimitry Andric /// Retrieve the record type that describes the state of an 115236981b17SDimitry Andric /// Objective-C fast enumeration loop (for..in). 115336981b17SDimitry Andric QualType getObjCFastEnumerationStateType(); 1154ec2b103cSEd Schouten 115506d4ba38SDimitry Andric // Produce code for this constructor/destructor. This method doesn't try 115606d4ba38SDimitry Andric // to apply any ABI rules about which other constructors/destructors 115706d4ba38SDimitry Andric // are needed or if they are alias to each other. 115822989816SDimitry Andric llvm::Function *codegenCXXStructor(GlobalDecl GD); 1159ec2b103cSEd Schouten 116006d4ba38SDimitry Andric /// Return the address of the constructor/destructor of the given type. 116145b53394SDimitry Andric llvm::Constant * 116222989816SDimitry Andric getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr, 116306d4ba38SDimitry Andric llvm::FunctionType *FnType = nullptr, 1164bab175ecSDimitry Andric bool DontDefer = false, 116522989816SDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition) { 116622989816SDimitry Andric return cast<llvm::Constant>(getAddrAndTypeOfCXXStructor(GD, FnInfo, FnType, 116722989816SDimitry Andric DontDefer, 116822989816SDimitry Andric IsForDefinition) 116922989816SDimitry Andric .getCallee()); 117022989816SDimitry Andric } 117122989816SDimitry Andric 117222989816SDimitry Andric llvm::FunctionCallee getAddrAndTypeOfCXXStructor( 117322989816SDimitry Andric GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr, 117422989816SDimitry Andric llvm::FunctionType *FnType = nullptr, bool DontDefer = false, 1175bab175ecSDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition); 1176ec2b103cSEd Schouten 11779f4dbff6SDimitry Andric /// Given a builtin id for a function like "__builtin_fabsf", return a 11789f4dbff6SDimitry Andric /// Function* for "fabsf". 1179bab175ecSDimitry Andric llvm::Constant *getBuiltinLibFunction(const FunctionDecl *FD, 11804c8b2481SRoman Divacky unsigned BuiltinID); 1181ec2b103cSEd Schouten 1182e3b55780SDimitry Andric llvm::Function *getIntrinsic(unsigned IID, 1183e3b55780SDimitry Andric ArrayRef<llvm::Type *> Tys = std::nullopt); 1184ec2b103cSEd Schouten 11859f4dbff6SDimitry Andric /// Emit code for a single top level declaration. 1186ec2b103cSEd Schouten void EmitTopLevelDecl(Decl *D); 1187ec2b103cSEd Schouten 118848675466SDimitry Andric /// Stored a deferred empty coverage mapping for an unused 118906d4ba38SDimitry Andric /// and thus uninstrumented top level declaration. 119006d4ba38SDimitry Andric void AddDeferredUnusedCoverageMapping(Decl *D); 119106d4ba38SDimitry Andric 119248675466SDimitry Andric /// Remove the deferred empty coverage mapping as this 119306d4ba38SDimitry Andric /// declaration is actually instrumented. 119406d4ba38SDimitry Andric void ClearUnusedCoverageMapping(const Decl *D); 119506d4ba38SDimitry Andric 119648675466SDimitry Andric /// Emit all the deferred coverage mappings 119706d4ba38SDimitry Andric /// for the uninstrumented functions. 119806d4ba38SDimitry Andric void EmitDeferredUnusedCoverageMappings(); 119906d4ba38SDimitry Andric 1200cfca06d7SDimitry Andric /// Emit an alias for "main" if it has no arguments (needed for wasm). 1201cfca06d7SDimitry Andric void EmitMainVoidAlias(); 1202cfca06d7SDimitry Andric 12039f4dbff6SDimitry Andric /// Tell the consumer that this variable has been instantiated. 1204dbe13110SDimitry Andric void HandleCXXStaticMemberVarInstantiation(VarDecl *VD); 1205dbe13110SDimitry Andric 120648675466SDimitry Andric /// If the declaration has internal linkage but is inside an 12076a037251SDimitry Andric /// extern "C" linkage specification, prepare to emit an alias for it 12086a037251SDimitry Andric /// to the expected name. 12096a037251SDimitry Andric template<typename SomeDecl> 12106a037251SDimitry Andric void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV); 12116a037251SDimitry Andric 12129f4dbff6SDimitry Andric /// Add a global to a list to be added to the llvm.used metadata. 12139f4dbff6SDimitry Andric void addUsedGlobal(llvm::GlobalValue *GV); 1214ec2b103cSEd Schouten 12159f4dbff6SDimitry Andric /// Add a global to a list to be added to the llvm.compiler.used metadata. 12169f4dbff6SDimitry Andric void addCompilerUsedGlobal(llvm::GlobalValue *GV); 12179f4dbff6SDimitry Andric 1218344a3780SDimitry Andric /// Add a global to a list to be added to the llvm.compiler.used metadata. 1219344a3780SDimitry Andric void addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV); 1220344a3780SDimitry Andric 12219f4dbff6SDimitry Andric /// Add a destructor and object to add to the C++ global destructor function. AddCXXDtorEntry(llvm::FunctionCallee DtorFn,llvm::Constant * Object)122222989816SDimitry Andric void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object) { 1223cfca06d7SDimitry Andric CXXGlobalDtorsOrStermFinalizers.emplace_back(DtorFn.getFunctionType(), 1224cfca06d7SDimitry Andric DtorFn.getCallee(), Object); 1225cfca06d7SDimitry Andric } 1226cfca06d7SDimitry Andric 1227cfca06d7SDimitry Andric /// Add an sterm finalizer to the C++ global cleanup function. AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn)1228cfca06d7SDimitry Andric void AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn) { 1229cfca06d7SDimitry Andric CXXGlobalDtorsOrStermFinalizers.emplace_back(DtorFn.getFunctionType(), 1230cfca06d7SDimitry Andric DtorFn.getCallee(), nullptr); 12314ba67500SRoman Divacky } 1232c0c7bca4SRoman Divacky 1233b60736ecSDimitry Andric /// Add an sterm finalizer to its own llvm.global_dtors entry. AddCXXStermFinalizerToGlobalDtor(llvm::Function * StermFinalizer,int Priority)1234b60736ecSDimitry Andric void AddCXXStermFinalizerToGlobalDtor(llvm::Function *StermFinalizer, 1235b60736ecSDimitry Andric int Priority) { 1236b60736ecSDimitry Andric AddGlobalDtor(StermFinalizer, Priority); 1237b60736ecSDimitry Andric } 1238b60736ecSDimitry Andric AddCXXPrioritizedStermFinalizerEntry(llvm::Function * StermFinalizer,int Priority)1239344a3780SDimitry Andric void AddCXXPrioritizedStermFinalizerEntry(llvm::Function *StermFinalizer, 1240344a3780SDimitry Andric int Priority) { 1241344a3780SDimitry Andric OrderGlobalInitsOrStermFinalizers Key(Priority, 1242344a3780SDimitry Andric PrioritizedCXXStermFinalizers.size()); 1243344a3780SDimitry Andric PrioritizedCXXStermFinalizers.push_back( 1244344a3780SDimitry Andric std::make_pair(Key, StermFinalizer)); 1245344a3780SDimitry Andric } 1246344a3780SDimitry Andric 124722989816SDimitry Andric /// Create or return a runtime function declaration with the specified type 1248706b4fc4SDimitry Andric /// and name. If \p AssumeConvergent is true, the call will have the 1249706b4fc4SDimitry Andric /// convergent attribute added. 125022989816SDimitry Andric llvm::FunctionCallee 1251bab175ecSDimitry Andric CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, 12527442d6faSDimitry Andric llvm::AttributeList ExtraAttrs = llvm::AttributeList(), 1253706b4fc4SDimitry Andric bool Local = false, bool AssumeConvergent = false); 1254706b4fc4SDimitry Andric 12559f4dbff6SDimitry Andric /// Create a new runtime global variable with the specified type and name. 125636981b17SDimitry Andric llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty, 125736981b17SDimitry Andric StringRef Name); 1258ec2b103cSEd Schouten 12593d1dcd9bSDimitry Andric ///@name Custom Blocks Runtime Interfaces 12603d1dcd9bSDimitry Andric ///@{ 12613d1dcd9bSDimitry Andric 12623d1dcd9bSDimitry Andric llvm::Constant *getNSConcreteGlobalBlock(); 12633d1dcd9bSDimitry Andric llvm::Constant *getNSConcreteStackBlock(); 126422989816SDimitry Andric llvm::FunctionCallee getBlockObjectAssign(); 126522989816SDimitry Andric llvm::FunctionCallee getBlockObjectDispose(); 12663d1dcd9bSDimitry Andric 12673d1dcd9bSDimitry Andric ///@} 12683d1dcd9bSDimitry Andric 126922989816SDimitry Andric llvm::Function *getLLVMLifetimeStartFn(); 127022989816SDimitry Andric llvm::Function *getLLVMLifetimeEndFn(); 1271809500fcSDimitry Andric 12729f4dbff6SDimitry Andric // Make sure that this type is translated. 127301af97d3SDimitry Andric void UpdateCompletedType(const TagDecl *TD); 1274ec2b103cSEd Schouten 1275bca07a45SDimitry Andric llvm::Constant *getMemberPointerConstant(const UnaryOperator *e); 1276bca07a45SDimitry Andric 127748675466SDimitry Andric /// Emit type info if type of an expression is a variably modified 127845b53394SDimitry Andric /// type. Also emit proper debug info for cast types. 127945b53394SDimitry Andric void EmitExplicitCastExprType(const ExplicitCastExpr *E, 128045b53394SDimitry Andric CodeGenFunction *CGF = nullptr); 128145b53394SDimitry Andric 12829f4dbff6SDimitry Andric /// Return the result of value-initializing the given type, i.e. a null 12839f4dbff6SDimitry Andric /// expression of the given type. This is usually, but not always, an LLVM 12849f4dbff6SDimitry Andric /// null constant. 1285ec2b103cSEd Schouten llvm::Constant *EmitNullConstant(QualType T); 1286ec2b103cSEd Schouten 12879f4dbff6SDimitry Andric /// Return a null constant appropriate for zero-initializing a base class with 12889f4dbff6SDimitry Andric /// the given type. This is usually, but not always, an LLVM null constant. 128936981b17SDimitry Andric llvm::Constant *EmitNullConstantForBase(const CXXRecordDecl *Record); 1290ec2b103cSEd Schouten 12919f4dbff6SDimitry Andric /// Emit a general error that something can't be done. 129236981b17SDimitry Andric void Error(SourceLocation loc, StringRef error); 129301af97d3SDimitry Andric 12949f4dbff6SDimitry Andric /// Print out an error that codegen doesn't support the specified stmt yet. 1295bfef3995SDimitry Andric void ErrorUnsupported(const Stmt *S, const char *Type); 1296ec2b103cSEd Schouten 12979f4dbff6SDimitry Andric /// Print out an error that codegen doesn't support the specified decl yet. 1298bfef3995SDimitry Andric void ErrorUnsupported(const Decl *D, const char *Type); 1299ec2b103cSEd Schouten 13009f4dbff6SDimitry Andric /// Set the attributes on the LLVM function for the given decl and function 13019f4dbff6SDimitry Andric /// info. This applies attributes necessary for handling the ABI as well as 13029f4dbff6SDimitry Andric /// user specified attributes like section. 130348675466SDimitry Andric void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, 1304ec2b103cSEd Schouten const CGFunctionInfo &FI); 1305ec2b103cSEd Schouten 13069f4dbff6SDimitry Andric /// Set the LLVM function attributes (sext, zext, etc). 1307676fbe81SDimitry Andric void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, 1308344a3780SDimitry Andric llvm::Function *F, bool IsThunk); 1309ec2b103cSEd Schouten 13109f4dbff6SDimitry Andric /// Set the LLVM function attributes which only apply to a function 131106d4ba38SDimitry Andric /// definition. 1312ec2b103cSEd Schouten void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F); 1313ec2b103cSEd Schouten 1314b60736ecSDimitry Andric /// Set the LLVM function attributes that represent floating point 1315b60736ecSDimitry Andric /// environment. 1316b60736ecSDimitry Andric void setLLVMFunctionFEnvAttributes(const FunctionDecl *D, llvm::Function *F); 1317b60736ecSDimitry Andric 13189f4dbff6SDimitry Andric /// Return true iff the given type uses 'sret' when used as a return type. 13194e58654bSRoman Divacky bool ReturnTypeUsesSRet(const CGFunctionInfo &FI); 13204e58654bSRoman Divacky 1321ac9a064cSDimitry Andric /// Return true iff the given type has `inreg` set. 1322ac9a064cSDimitry Andric bool ReturnTypeHasInReg(const CGFunctionInfo &FI); 1323ac9a064cSDimitry Andric 13249f4dbff6SDimitry Andric /// Return true iff the given type uses an argument slot when 'sret' is used 13259f4dbff6SDimitry Andric /// as a return type. 13269f4dbff6SDimitry Andric bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI); 13279f4dbff6SDimitry Andric 13289f4dbff6SDimitry Andric /// Return true iff the given type uses 'fpret' when used as a return type. 13294e58654bSRoman Divacky bool ReturnTypeUsesFPRet(QualType ResultType); 1330ec2b103cSEd Schouten 13319f4dbff6SDimitry Andric /// Return true iff the given type uses 'fp2ret' when used as a return type. 1332dbe13110SDimitry Andric bool ReturnTypeUsesFP2Ret(QualType ResultType); 1333dbe13110SDimitry Andric 13349f4dbff6SDimitry Andric /// Get the LLVM attributes and calling convention to use for a particular 13359f4dbff6SDimitry Andric /// function type. 13364c8b2481SRoman Divacky /// 133797b17066SDimitry Andric /// \param Name - The function name. 13384c8b2481SRoman Divacky /// \param Info - The function type information. 133945b53394SDimitry Andric /// \param CalleeInfo - The callee information these attributes are being 134045b53394SDimitry Andric /// constructed for. If valid, the attributes applied to this decl may 134145b53394SDimitry Andric /// contribute to the function attributes and calling convention. 1342583e75ccSDimitry Andric /// \param Attrs [out] - On return, the attribute list to use. 13434c8b2481SRoman Divacky /// \param CallingConv [out] - On return, the LLVM calling convention to use. 134497b17066SDimitry Andric void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, 1345583e75ccSDimitry Andric CGCalleeInfo CalleeInfo, 1346583e75ccSDimitry Andric llvm::AttributeList &Attrs, unsigned &CallingConv, 1347344a3780SDimitry Andric bool AttrOnCallSite, bool IsThunk); 134845b53394SDimitry Andric 1349b1c73532SDimitry Andric /// Adjust Memory attribute to ensure that the BE gets the right attribute 1350b1c73532SDimitry Andric // in order to generate the library call or the intrinsic for the function 1351b1c73532SDimitry Andric // name 'Name'. 1352b1c73532SDimitry Andric void AdjustMemoryAttribute(StringRef Name, CGCalleeInfo CalleeInfo, 1353b1c73532SDimitry Andric llvm::AttributeList &Attrs); 1354cfca06d7SDimitry Andric 1355cfca06d7SDimitry Andric /// Like the overload taking a `Function &`, but intended specifically 1356cfca06d7SDimitry Andric /// for frontends that want to build on Clang's target-configuration logic. 1357cfca06d7SDimitry Andric void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs); 13587442d6faSDimitry Andric 135936981b17SDimitry Andric StringRef getMangledName(GlobalDecl GD); 13609f4dbff6SDimitry Andric StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD); 1361145449b1SDimitry Andric const GlobalDecl getMangledNameDecl(StringRef); 1362ec2b103cSEd Schouten 1363ec2b103cSEd Schouten void EmitTentativeDefinition(const VarDecl *D); 1364ec2b103cSEd Schouten 1365ac9a064cSDimitry Andric void EmitExternalDeclaration(const DeclaratorDecl *D); 1366706b4fc4SDimitry Andric 13675e20cdd8SDimitry Andric void EmitVTable(CXXRecordDecl *Class); 1368d7279c4cSRoman Divacky 13692b6b257fSDimitry Andric void RefreshTypeCacheForClass(const CXXRecordDecl *Class); 13702b6b257fSDimitry Andric 137148675466SDimitry Andric /// Appends Opts to the "llvm.linker.options" metadata value. 1372bfef3995SDimitry Andric void AppendLinkerOptions(StringRef Opts); 1373bfef3995SDimitry Andric 137448675466SDimitry Andric /// Appends a detect mismatch command to the linker options. 1375bfef3995SDimitry Andric void AddDetectMismatch(StringRef Name, StringRef Value); 1376bfef3995SDimitry Andric 137722989816SDimitry Andric /// Appends a dependent lib to the appropriate metadata value. 1378bfef3995SDimitry Andric void AddDependentLib(StringRef Lib); 1379bfef3995SDimitry Andric 138048675466SDimitry Andric 1381bfef3995SDimitry Andric llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD); 1382bfef3995SDimitry Andric setFunctionLinkage(GlobalDecl GD,llvm::Function * F)13839f4dbff6SDimitry Andric void setFunctionLinkage(GlobalDecl GD, llvm::Function *F) { 13849f4dbff6SDimitry Andric F->setLinkage(getFunctionLinkage(GD)); 1385d7279c4cSRoman Divacky } 1386d7279c4cSRoman Divacky 13879f4dbff6SDimitry Andric /// Return the appropriate linkage for the vtable, VTT, and type information 13889f4dbff6SDimitry Andric /// of the given class. 1389bca07a45SDimitry Andric llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD); 1390ee791ddeSRoman Divacky 13919f4dbff6SDimitry Andric /// Return the store size, in character units, of the given LLVM type. 139236981b17SDimitry Andric CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const; 1393ecb7e5c8SRoman Divacky 13949f4dbff6SDimitry Andric /// Returns LLVM linkage for a declarator. 1395bca07a45SDimitry Andric llvm::GlobalValue::LinkageTypes 1396b1c73532SDimitry Andric getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage); 13979f4dbff6SDimitry Andric 13989f4dbff6SDimitry Andric /// Returns LLVM linkage for a declarator. 13999f4dbff6SDimitry Andric llvm::GlobalValue::LinkageTypes 1400b1c73532SDimitry Andric getLLVMLinkageVarDefinition(const VarDecl *VD); 1401bca07a45SDimitry Andric 140236981b17SDimitry Andric /// Emit all the global annotations. 140336981b17SDimitry Andric void EmitGlobalAnnotations(); 1404ec2b103cSEd Schouten 140536981b17SDimitry Andric /// Emit an annotation string. 1406809500fcSDimitry Andric llvm::Constant *EmitAnnotationString(StringRef Str); 140736981b17SDimitry Andric 140836981b17SDimitry Andric /// Emit the annotation's translation unit. 140936981b17SDimitry Andric llvm::Constant *EmitAnnotationUnit(SourceLocation Loc); 141036981b17SDimitry Andric 141136981b17SDimitry Andric /// Emit the annotation line number. 141236981b17SDimitry Andric llvm::Constant *EmitAnnotationLineNo(SourceLocation L); 141336981b17SDimitry Andric 1414b60736ecSDimitry Andric /// Emit additional args of the annotation. 1415b60736ecSDimitry Andric llvm::Constant *EmitAnnotationArgs(const AnnotateAttr *Attr); 1416b60736ecSDimitry Andric 14179f4dbff6SDimitry Andric /// Generate the llvm::ConstantStruct which contains the annotation 14189f4dbff6SDimitry Andric /// information for a given GlobalValue. The annotation struct is 141936981b17SDimitry Andric /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the 142036981b17SDimitry Andric /// GlobalValue being annotated. The second field is the constant string 142136981b17SDimitry Andric /// created from the AnnotateAttr's annotation. The third field is a constant 142236981b17SDimitry Andric /// string containing the name of the translation unit. The fourth field is 142336981b17SDimitry Andric /// the line number in the file of the annotated value declaration. 142436981b17SDimitry Andric llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV, 142536981b17SDimitry Andric const AnnotateAttr *AA, 142636981b17SDimitry Andric SourceLocation L); 142736981b17SDimitry Andric 142836981b17SDimitry Andric /// Add global annotations that are set on D, for the global GV. Those 142936981b17SDimitry Andric /// annotations are emitted during finalization of the LLVM code. 143036981b17SDimitry Andric void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); 143136981b17SDimitry Andric 1432344a3780SDimitry Andric bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn, 1433461a67faSDimitry Andric SourceLocation Loc) const; 143406d4ba38SDimitry Andric 1435145449b1SDimitry Andric bool isInNoSanitizeList(SanitizerMask Kind, llvm::GlobalVariable *GV, 1436145449b1SDimitry Andric SourceLocation Loc, QualType Ty, 1437145449b1SDimitry Andric StringRef Category = StringRef()) const; 143806d4ba38SDimitry Andric 14397442d6faSDimitry Andric /// Imbue XRay attributes to a function, applying the always/never attribute 14407442d6faSDimitry Andric /// lists in the process. Returns true if we did imbue attributes this way, 14417442d6faSDimitry Andric /// false otherwise. 14427442d6faSDimitry Andric bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, 14437442d6faSDimitry Andric StringRef Category = StringRef()) const; 14447442d6faSDimitry Andric 14454b4fe385SDimitry Andric /// \returns true if \p Fn at \p Loc should be excluded from profile 14464b4fe385SDimitry Andric /// instrumentation by the SCL passed by \p -fprofile-list. 1447e3b55780SDimitry Andric ProfileList::ExclusionType 1448e3b55780SDimitry Andric isFunctionBlockedByProfileList(llvm::Function *Fn, SourceLocation Loc) const; 14494b4fe385SDimitry Andric 14504b4fe385SDimitry Andric /// \returns true if \p Fn at \p Loc should be excluded from profile 14514b4fe385SDimitry Andric /// instrumentation. 1452e3b55780SDimitry Andric ProfileList::ExclusionType 1453e3b55780SDimitry Andric isFunctionBlockedFromProfileInstr(llvm::Function *Fn, 14544b4fe385SDimitry Andric SourceLocation Loc) const; 1455b60736ecSDimitry Andric getSanitizerMetadata()145606d4ba38SDimitry Andric SanitizerMetadata *getSanitizerMetadata() { 145706d4ba38SDimitry Andric return SanitizerMD.get(); 1458809500fcSDimitry Andric } 1459809500fcSDimitry Andric addDeferredVTable(const CXXRecordDecl * RD)1460809500fcSDimitry Andric void addDeferredVTable(const CXXRecordDecl *RD) { 1461809500fcSDimitry Andric DeferredVTables.push_back(RD); 1462809500fcSDimitry Andric } 1463809500fcSDimitry Andric 146448675466SDimitry Andric /// Emit code for a single global function or var decl. Forward declarations 14659f4dbff6SDimitry Andric /// are emitted lazily. 1466bfef3995SDimitry Andric void EmitGlobal(GlobalDecl D); 1467bfef3995SDimitry Andric 146806d4ba38SDimitry Andric bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D); 146906d4ba38SDimitry Andric 147036981b17SDimitry Andric llvm::GlobalValue *GetGlobalValue(StringRef Ref); 147136981b17SDimitry Andric 14729f4dbff6SDimitry Andric /// Set attributes which are common to any form of a global definition (alias, 14739f4dbff6SDimitry Andric /// Objective-C method, function, global variable). 1474ec2b103cSEd Schouten /// 1475ec2b103cSEd Schouten /// NOTE: This should only be called for definitions. 147648675466SDimitry Andric void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV); 147706d4ba38SDimitry Andric 147806d4ba38SDimitry Andric void addReplacement(StringRef Name, llvm::Constant *C); 147906d4ba38SDimitry Andric 148045b53394SDimitry Andric void addGlobalValReplacement(llvm::GlobalValue *GV, llvm::Constant *C); 148145b53394SDimitry Andric 148248675466SDimitry Andric /// Emit a code for threadprivate directive. 148306d4ba38SDimitry Andric /// \param D Threadprivate declaration. 148406d4ba38SDimitry Andric void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D); 148506d4ba38SDimitry Andric 148648675466SDimitry Andric /// Emit a code for declare reduction construct. 14872b6b257fSDimitry Andric void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D, 14882b6b257fSDimitry Andric CodeGenFunction *CGF = nullptr); 148951ece4aaSDimitry Andric 149022989816SDimitry Andric /// Emit a code for declare mapper construct. 149122989816SDimitry Andric void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D, 149222989816SDimitry Andric CodeGenFunction *CGF = nullptr); 149322989816SDimitry Andric 1494676fbe81SDimitry Andric /// Emit a code for requires directive. 1495676fbe81SDimitry Andric /// \param D Requires declaration 1496676fbe81SDimitry Andric void EmitOMPRequiresDecl(const OMPRequiresDecl *D); 1497676fbe81SDimitry Andric 1498344a3780SDimitry Andric /// Emit a code for the allocate directive. 1499344a3780SDimitry Andric /// \param D The allocate declaration 1500344a3780SDimitry Andric void EmitOMPAllocateDecl(const OMPAllocateDecl *D); 1501344a3780SDimitry Andric 1502145449b1SDimitry Andric /// Return the alignment specified in an allocate directive, if present. 1503e3b55780SDimitry Andric std::optional<CharUnits> getOMPAllocateAlignment(const VarDecl *VD); 1504145449b1SDimitry Andric 15052b6b257fSDimitry Andric /// Returns whether the given record has hidden LTO visibility and therefore 15062b6b257fSDimitry Andric /// may participate in (single-module) CFI and whole-program vtable 15072b6b257fSDimitry Andric /// optimization. 15082b6b257fSDimitry Andric bool HasHiddenLTOVisibility(const CXXRecordDecl *RD); 15092b6b257fSDimitry Andric 1510145449b1SDimitry Andric /// Returns whether the given record has public LTO visibility (regardless of 1511145449b1SDimitry Andric /// -lto-whole-program-visibility) and therefore may not participate in 1512145449b1SDimitry Andric /// (single-module) CFI and whole-program vtable optimization. 1513145449b1SDimitry Andric bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD); 1514cfca06d7SDimitry Andric 1515519fc96cSDimitry Andric /// Returns the vcall visibility of the given type. This is the scope in which 1516519fc96cSDimitry Andric /// a virtual function call could be made which ends up being dispatched to a 1517519fc96cSDimitry Andric /// member function of this class. This scope can be wider than the visibility 1518519fc96cSDimitry Andric /// of the class itself when the class has a more-visible dynamic base class. 1519b60736ecSDimitry Andric /// The client should pass in an empty Visited set, which is used to prevent 1520b60736ecSDimitry Andric /// redundant recursive processing. 1521519fc96cSDimitry Andric llvm::GlobalObject::VCallVisibility 1522b60736ecSDimitry Andric GetVCallVisibilityLevel(const CXXRecordDecl *RD, 1523b60736ecSDimitry Andric llvm::DenseSet<const CXXRecordDecl *> &Visited); 1524519fc96cSDimitry Andric 15252b6b257fSDimitry Andric /// Emit type metadata for the given vtable using the given layout. 1526519fc96cSDimitry Andric void EmitVTableTypeMetadata(const CXXRecordDecl *RD, 1527519fc96cSDimitry Andric llvm::GlobalVariable *VTable, 15285e20cdd8SDimitry Andric const VTableLayout &VTLayout); 15295e20cdd8SDimitry Andric 1530e3b55780SDimitry Andric llvm::Type *getVTableComponentType() const; 1531e3b55780SDimitry Andric 15322b6b257fSDimitry Andric /// Generate a cross-DSO type identifier for MD. 15332b6b257fSDimitry Andric llvm::ConstantInt *CreateCrossDsoCfiTypeId(llvm::Metadata *MD); 153445b53394SDimitry Andric 1535e3b55780SDimitry Andric /// Generate a KCFI type identifier for T. 1536e3b55780SDimitry Andric llvm::ConstantInt *CreateKCFITypeId(QualType T); 1537e3b55780SDimitry Andric 153845b53394SDimitry Andric /// Create a metadata identifier for the given type. This may either be an 153945b53394SDimitry Andric /// MDString (for external identifiers) or a distinct unnamed MDNode (for 154045b53394SDimitry Andric /// internal identifiers). 154145b53394SDimitry Andric llvm::Metadata *CreateMetadataIdentifierForType(QualType T); 154245b53394SDimitry Andric 154348675466SDimitry Andric /// Create a metadata identifier that is intended to be used to check virtual 154448675466SDimitry Andric /// calls via a member function pointer. 154548675466SDimitry Andric llvm::Metadata *CreateMetadataIdentifierForVirtualMemPtrType(QualType T); 154648675466SDimitry Andric 1547461a67faSDimitry Andric /// Create a metadata identifier for the generalization of the given type. 1548461a67faSDimitry Andric /// This may either be an MDString (for external identifiers) or a distinct 1549461a67faSDimitry Andric /// unnamed MDNode (for internal identifiers). 1550461a67faSDimitry Andric llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T); 1551461a67faSDimitry Andric 15522b6b257fSDimitry Andric /// Create and attach type metadata to the given function. 155348675466SDimitry Andric void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD, 155448675466SDimitry Andric llvm::Function *F); 155545b53394SDimitry Andric 1556e3b55780SDimitry Andric /// Set type metadata to the given function. 1557e3b55780SDimitry Andric void setKCFIType(const FunctionDecl *FD, llvm::Function *F); 1558e3b55780SDimitry Andric 1559e3b55780SDimitry Andric /// Emit KCFI type identifier constants and remove unused identifiers. 1560e3b55780SDimitry Andric void finalizeKCFITypes(); 1561e3b55780SDimitry Andric 1562344a3780SDimitry Andric /// Whether this function's return type has no side effects, and thus may 1563344a3780SDimitry Andric /// be trivially discarded if it is unused. 1564e3b55780SDimitry Andric bool MayDropFunctionReturn(const ASTContext &Context, 1565e3b55780SDimitry Andric QualType ReturnType) const; 1566344a3780SDimitry Andric 15672b6b257fSDimitry Andric /// Returns whether this module needs the "all-vtables" type identifier. 15682b6b257fSDimitry Andric bool NeedAllVtablesTypeId() const; 15692b6b257fSDimitry Andric 15702b6b257fSDimitry Andric /// Create and attach type metadata for the given vtable. 15712b6b257fSDimitry Andric void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, 15722e645aa5SDimitry Andric const CXXRecordDecl *RD); 15732e645aa5SDimitry Andric 157448675466SDimitry Andric /// Return a vector of most-base classes for RD. This is used to implement 157548675466SDimitry Andric /// control flow integrity checks for member function pointers. 157648675466SDimitry Andric /// 157748675466SDimitry Andric /// A most-base class of a class C is defined as a recursive base class of C, 157848675466SDimitry Andric /// including C itself, that does not have any bases. 1579b1c73532SDimitry Andric SmallVector<const CXXRecordDecl *, 0> 158048675466SDimitry Andric getMostBaseClasses(const CXXRecordDecl *RD); 158148675466SDimitry Andric 158248675466SDimitry Andric /// Get the declaration of std::terminate for the platform. 158322989816SDimitry Andric llvm::FunctionCallee getTerminateFn(); 15845e20cdd8SDimitry Andric 15852b6b257fSDimitry Andric llvm::SanitizerStatReport &getSanStats(); 15862b6b257fSDimitry Andric 1587bab175ecSDimitry Andric llvm::Value * 1588bab175ecSDimitry Andric createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF); 1589bab175ecSDimitry Andric 159022989816SDimitry Andric /// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument 159122989816SDimitry Andric /// information in the program executable. The argument information stored 159222989816SDimitry Andric /// includes the argument name, its type, the address and access qualifiers 159322989816SDimitry Andric /// used. This helper can be used to generate metadata for source code kernel 159422989816SDimitry Andric /// function as well as generated implicitly kernels. If a kernel is generated 159522989816SDimitry Andric /// implicitly null value has to be passed to the last two parameters, 159622989816SDimitry Andric /// otherwise all parameters must have valid non-null values. 159722989816SDimitry Andric /// \param FN is a pointer to IR function being generated. 159822989816SDimitry Andric /// \param FD is a pointer to function declaration if any. 159922989816SDimitry Andric /// \param CGF is a pointer to CodeGenFunction that generates this function. 1600145449b1SDimitry Andric void GenKernelArgMetadata(llvm::Function *FN, 160122989816SDimitry Andric const FunctionDecl *FD = nullptr, 160222989816SDimitry Andric CodeGenFunction *CGF = nullptr); 160322989816SDimitry Andric 1604bab175ecSDimitry Andric /// Get target specific null pointer. 1605bab175ecSDimitry Andric /// \param T is the LLVM type of the null pointer. 1606bab175ecSDimitry Andric /// \param QT is the clang QualType of the null pointer. 1607bab175ecSDimitry Andric llvm::Constant *getNullPointer(llvm::PointerType *T, QualType QT); 1608bab175ecSDimitry Andric 1609cfca06d7SDimitry Andric CharUnits getNaturalTypeAlignment(QualType T, 1610cfca06d7SDimitry Andric LValueBaseInfo *BaseInfo = nullptr, 1611cfca06d7SDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr, 1612cfca06d7SDimitry Andric bool forPointeeType = false); 1613cfca06d7SDimitry Andric CharUnits getNaturalPointeeTypeAlignment(QualType T, 1614cfca06d7SDimitry Andric LValueBaseInfo *BaseInfo = nullptr, 1615cfca06d7SDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr); 1616cfca06d7SDimitry Andric bool stopAutoInit(); 1617cfca06d7SDimitry Andric 1618145449b1SDimitry Andric /// Print the postfix for externalized static variable or kernels for single 1619145449b1SDimitry Andric /// source offloading languages CUDA and HIP. The unique postfix is created 1620145449b1SDimitry Andric /// using either the CUID argument, or the file's UniqueID and active macros. 1621145449b1SDimitry Andric /// The fallback method without a CUID requires that the offloading toolchain 1622145449b1SDimitry Andric /// does not define separate macros via the -cc1 options. 1623145449b1SDimitry Andric void printPostfixForExternalizedDecl(llvm::raw_ostream &OS, 1624145449b1SDimitry Andric const Decl *D) const; 1625145449b1SDimitry Andric 1626145449b1SDimitry Andric /// Move some lazily-emitted states to the NewBuilder. This is especially 1627145449b1SDimitry Andric /// essential for the incremental parsing environment like Clang Interpreter, 1628145449b1SDimitry Andric /// because we'll lose all important information after each repl. 16294b4fe385SDimitry Andric void moveLazyEmissionStates(CodeGenModule *NewBuilder); 1630344a3780SDimitry Andric 1631b1c73532SDimitry Andric /// Emit the IR encoding to attach the CUDA launch bounds attribute to \p F. 1632b1c73532SDimitry Andric /// If \p MaxThreadsVal is not nullptr, the max threads value is stored in it, 1633b1c73532SDimitry Andric /// if a valid one was found. 1634b1c73532SDimitry Andric void handleCUDALaunchBoundsAttr(llvm::Function *F, 1635b1c73532SDimitry Andric const CUDALaunchBoundsAttr *A, 1636b1c73532SDimitry Andric int32_t *MaxThreadsVal = nullptr, 1637b1c73532SDimitry Andric int32_t *MinBlocksVal = nullptr, 1638b1c73532SDimitry Andric int32_t *MaxClusterRankVal = nullptr); 1639b1c73532SDimitry Andric 1640b1c73532SDimitry Andric /// Emit the IR encoding to attach the AMD GPU flat-work-group-size attribute 1641b1c73532SDimitry Andric /// to \p F. Alternatively, the work group size can be taken from a \p 1642b1c73532SDimitry Andric /// ReqdWGS. If \p MinThreadsVal is not nullptr, the min threads value is 1643b1c73532SDimitry Andric /// stored in it, if a valid one was found. If \p MaxThreadsVal is not 1644b1c73532SDimitry Andric /// nullptr, the max threads value is stored in it, if a valid one was found. 1645b1c73532SDimitry Andric void handleAMDGPUFlatWorkGroupSizeAttr( 1646b1c73532SDimitry Andric llvm::Function *F, const AMDGPUFlatWorkGroupSizeAttr *A, 1647b1c73532SDimitry Andric const ReqdWorkGroupSizeAttr *ReqdWGS = nullptr, 1648b1c73532SDimitry Andric int32_t *MinThreadsVal = nullptr, int32_t *MaxThreadsVal = nullptr); 1649b1c73532SDimitry Andric 1650b1c73532SDimitry Andric /// Emit the IR encoding to attach the AMD GPU waves-per-eu attribute to \p F. 1651b1c73532SDimitry Andric void handleAMDGPUWavesPerEUAttr(llvm::Function *F, 1652b1c73532SDimitry Andric const AMDGPUWavesPerEUAttr *A); 1653b1c73532SDimitry Andric 1654b1c73532SDimitry Andric llvm::Constant * 1655b1c73532SDimitry Andric GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, LangAS AddrSpace, 1656b1c73532SDimitry Andric const VarDecl *D, 1657b1c73532SDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition); 1658b1c73532SDimitry Andric 1659b1c73532SDimitry Andric // FIXME: Hardcoding priority here is gross. 1660b1c73532SDimitry Andric void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535, 1661b1c73532SDimitry Andric unsigned LexOrder = ~0U, 1662b1c73532SDimitry Andric llvm::Constant *AssociatedData = nullptr); 1663b1c73532SDimitry Andric void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535, 1664b1c73532SDimitry Andric bool IsDtorAttrFunc = false); 1665b1c73532SDimitry Andric 1666ac9a064cSDimitry Andric // Return whether structured convergence intrinsics should be generated for 1667ac9a064cSDimitry Andric // this target. shouldEmitConvergenceTokens()1668ac9a064cSDimitry Andric bool shouldEmitConvergenceTokens() const { 1669ac9a064cSDimitry Andric // TODO: this should probably become unconditional once the controlled 1670ac9a064cSDimitry Andric // convergence becomes the norm. 1671ac9a064cSDimitry Andric return getTriple().isSPIRVLogical(); 1672ac9a064cSDimitry Andric } 1673ac9a064cSDimitry Andric addUndefinedGlobalForTailCall(std::pair<const FunctionDecl *,SourceLocation> Global)1674ac9a064cSDimitry Andric void addUndefinedGlobalForTailCall( 1675ac9a064cSDimitry Andric std::pair<const FunctionDecl *, SourceLocation> Global) { 1676ac9a064cSDimitry Andric MustTailCallUndefinedGlobals.insert(Global); 1677ac9a064cSDimitry Andric } 1678ac9a064cSDimitry Andric 167906d4ba38SDimitry Andric private: 1680ac9a064cSDimitry Andric bool shouldDropDLLAttribute(const Decl *D, const llvm::GlobalValue *GV) const; 1681ac9a064cSDimitry Andric 16827442d6faSDimitry Andric llvm::Constant *GetOrCreateLLVMFunction( 16837442d6faSDimitry Andric StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable, 16847442d6faSDimitry Andric bool DontDefer = false, bool IsThunk = false, 16857442d6faSDimitry Andric llvm::AttributeList ExtraAttrs = llvm::AttributeList(), 1686bab175ecSDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition); 168706d4ba38SDimitry Andric 1688ac9a064cSDimitry Andric // Adds a declaration to the list of multi version functions if not present. 1689ac9a064cSDimitry Andric void AddDeferredMultiVersionResolverToEmit(GlobalDecl GD); 1690ac9a064cSDimitry Andric 1691145449b1SDimitry Andric // References to multiversion functions are resolved through an implicitly 1692145449b1SDimitry Andric // defined resolver function. This function is responsible for creating 1693145449b1SDimitry Andric // the resolver symbol for the provided declaration. The value returned 1694145449b1SDimitry Andric // will be for an ifunc (llvm::GlobalIFunc) if the current target supports 1695145449b1SDimitry Andric // that feature and for a regular function (llvm::GlobalValue) otherwise. 1696145449b1SDimitry Andric llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD); 1697145449b1SDimitry Andric 1698145449b1SDimitry Andric // In scenarios where a function is not known to be a multiversion function 1699145449b1SDimitry Andric // until a later declaration, it is sometimes necessary to change the 1700145449b1SDimitry Andric // previously created mangled name to align with requirements of whatever 1701145449b1SDimitry Andric // multiversion function kind the function is now known to be. This function 1702145449b1SDimitry Andric // is responsible for performing such mangled name updates. 17036f8fc217SDimitry Andric void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD, 17046f8fc217SDimitry Andric StringRef &CurName); 170548675466SDimitry Andric 1706676fbe81SDimitry Andric bool GetCPUAndFeaturesAttributes(GlobalDecl GD, 17077fa27ce4SDimitry Andric llvm::AttrBuilder &AttrBuilder, 17087fa27ce4SDimitry Andric bool SetTargetFeatures = true); 170948675466SDimitry Andric void setNonAliasAttributes(GlobalDecl GD, llvm::GlobalObject *GO); 1710ec2b103cSEd Schouten 17119f4dbff6SDimitry Andric /// Set function attributes for a function declaration. 171206d4ba38SDimitry Andric void SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, 171348675466SDimitry Andric bool IsIncompleteFunction, bool IsThunk); 1714ec2b103cSEd Schouten 17159f4dbff6SDimitry Andric void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr); 1716ec2b103cSEd Schouten 17179f4dbff6SDimitry Andric void EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV); 1718676fbe81SDimitry Andric void EmitMultiVersionFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV); 1719676fbe81SDimitry Andric 17202b6b257fSDimitry Andric void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false); 1721706b4fc4SDimitry Andric void EmitExternalVarDeclaration(const VarDecl *D); 1722ac9a064cSDimitry Andric void EmitExternalFunctionDeclaration(const FunctionDecl *D); 1723c0c7bca4SRoman Divacky void EmitAliasDefinition(GlobalDecl GD); 17242b6b257fSDimitry Andric void emitIFuncDefinition(GlobalDecl GD); 172548675466SDimitry Andric void emitCPUDispatchDefinition(GlobalDecl GD); 1726ec2b103cSEd Schouten void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); 17270883ccd9SRoman Divacky void EmitObjCIvarInitializations(ObjCImplementationDecl *D); 1728ec2b103cSEd Schouten 1729ec2b103cSEd Schouten // C++ related functions. 1730ec2b103cSEd Schouten 1731bab175ecSDimitry Andric void EmitDeclContext(const DeclContext *DC); 1732ec2b103cSEd Schouten void EmitLinkageSpec(const LinkageSpecDecl *D); 1733e3b55780SDimitry Andric void EmitTopLevelStmt(const TopLevelStmtDecl *D); 1734ec2b103cSEd Schouten 173548675466SDimitry Andric /// Emit the function that initializes C++ thread_local variables. 17366a037251SDimitry Andric void EmitCXXThreadLocalInitFunc(); 17376a037251SDimitry Andric 17384b4fe385SDimitry Andric /// Emit the function that initializes global variables for a C++ Module. 17394b4fe385SDimitry Andric void EmitCXXModuleInitFunc(clang::Module *Primary); 17404b4fe385SDimitry Andric 17419f4dbff6SDimitry Andric /// Emit the function that initializes C++ globals. 17424c8b2481SRoman Divacky void EmitCXXGlobalInitFunc(); 17434c8b2481SRoman Divacky 1744cfca06d7SDimitry Andric /// Emit the function that performs cleanup associated with C++ globals. 1745cfca06d7SDimitry Andric void EmitCXXGlobalCleanUpFunc(); 1746c0c7bca4SRoman Divacky 17479f4dbff6SDimitry Andric /// Emit the function that initializes the specified global (if PerformInit is 17489f4dbff6SDimitry Andric /// true) and registers its destructor. 1749bca07a45SDimitry Andric void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, 1750dbe13110SDimitry Andric llvm::GlobalVariable *Addr, 1751dbe13110SDimitry Andric bool PerformInit); 1752ee791ddeSRoman Divacky 17539f4dbff6SDimitry Andric void EmitPointerToInitFunc(const VarDecl *VD, llvm::GlobalVariable *Addr, 17549f4dbff6SDimitry Andric llvm::Function *InitFunc, InitSegAttr *ISA); 17559f4dbff6SDimitry Andric 1756bab175ecSDimitry Andric /// EmitCtorList - Generates a global array of functions and priorities using 1757bab175ecSDimitry Andric /// the given list and name. This array will have appending linkage and is 1758bab175ecSDimitry Andric /// suitable for use as a LLVM constructor or destructor array. Clears Fns. 1759bab175ecSDimitry Andric void EmitCtorList(CtorList &Fns, const char *GlobalName); 1760ec2b103cSEd Schouten 17619f4dbff6SDimitry Andric /// Emit any needed decls for which code generation was deferred. 1762809500fcSDimitry Andric void EmitDeferred(); 1763809500fcSDimitry Andric 1764416ada0fSDimitry Andric /// Try to emit external vtables as available_externally if they have emitted 1765416ada0fSDimitry Andric /// all inlined virtual functions. It runs after EmitDeferred() and therefore 1766416ada0fSDimitry Andric /// is not allowed to create new references to things that need to be emitted 1767416ada0fSDimitry Andric /// lazily. 1768416ada0fSDimitry Andric void EmitVTablesOpportunistically(); 1769416ada0fSDimitry Andric 1770bfef3995SDimitry Andric /// Call replaceAllUsesWith on all pairs in Replacements. 1771bfef3995SDimitry Andric void applyReplacements(); 1772bfef3995SDimitry Andric 177345b53394SDimitry Andric /// Call replaceAllUsesWith on all pairs in GlobalValReplacements. 177445b53394SDimitry Andric void applyGlobalValReplacements(); 177545b53394SDimitry Andric 1776bfef3995SDimitry Andric void checkAliases(); 1777bfef3995SDimitry Andric 177848675466SDimitry Andric std::map<int, llvm::TinyPtrVector<llvm::Function *>> DtorsUsingAtExit; 177948675466SDimitry Andric 178048675466SDimitry Andric /// Register functions annotated with __attribute__((destructor)) using 178148675466SDimitry Andric /// __cxa_atexit, if it is available, or atexit otherwise. 178248675466SDimitry Andric void registerGlobalDtorsWithAtExit(); 178348675466SDimitry Andric 1784b60736ecSDimitry Andric // When using sinit and sterm functions, unregister 1785b60736ecSDimitry Andric // __attribute__((destructor)) annotated functions which were previously 1786b60736ecSDimitry Andric // registered by the atexit subroutine using unatexit. 1787b60736ecSDimitry Andric void unregisterGlobalDtorsWithUnAtExit(); 1788b60736ecSDimitry Andric 1789145449b1SDimitry Andric /// Emit deferred multiversion function resolvers and associated variants. 179048675466SDimitry Andric void emitMultiVersionFunctions(); 179148675466SDimitry Andric 17929f4dbff6SDimitry Andric /// Emit any vtables which we deferred and still have a use for. 1793809500fcSDimitry Andric void EmitDeferredVTables(); 1794ec2b103cSEd Schouten 17957442d6faSDimitry Andric /// Emit a dummy function that reference a CoreFoundation symbol when 17967442d6faSDimitry Andric /// @available is used on Darwin. 17977442d6faSDimitry Andric void emitAtAvailableLinkGuard(); 17987442d6faSDimitry Andric 17999f4dbff6SDimitry Andric /// Emit the llvm.used and llvm.compiler.used metadata. 18009f4dbff6SDimitry Andric void emitLLVMUsed(); 1801809500fcSDimitry Andric 18024b4fe385SDimitry Andric /// For C++20 Itanium ABI, emit the initializers for the module. 18034b4fe385SDimitry Andric void EmitModuleInitializers(clang::Module *Primary); 18044b4fe385SDimitry Andric 180548675466SDimitry Andric /// Emit the link options introduced by imported modules. 1806809500fcSDimitry Andric void EmitModuleLinkOptions(); 1807ec2b103cSEd Schouten 1808145449b1SDimitry Andric /// Helper function for EmitStaticExternCAliases() to redirect ifuncs that 1809145449b1SDimitry Andric /// have a resolver name that matches 'Elem' to instead resolve to the name of 1810145449b1SDimitry Andric /// 'CppFunc'. This redirection is necessary in cases where 'Elem' has a name 1811145449b1SDimitry Andric /// that will be emitted as an alias of the name bound to 'CppFunc'; ifuncs 1812145449b1SDimitry Andric /// may not reference aliases. Redirection is only performed if 'Elem' is only 1813145449b1SDimitry Andric /// used by ifuncs in which case, 'Elem' is destroyed. 'true' is returned if 1814145449b1SDimitry Andric /// redirection is successful, and 'false' is returned otherwise. 1815145449b1SDimitry Andric bool CheckAndReplaceExternCIFuncs(llvm::GlobalValue *Elem, 1816145449b1SDimitry Andric llvm::GlobalValue *CppFunc); 1817145449b1SDimitry Andric 181848675466SDimitry Andric /// Emit aliases for internal-linkage declarations inside "C" language 18196a037251SDimitry Andric /// linkage specifications, giving them the "expected" name where possible. 18206a037251SDimitry Andric void EmitStaticExternCAliases(); 18216a037251SDimitry Andric 18224ba67500SRoman Divacky void EmitDeclMetadata(); 18234ba67500SRoman Divacky 182448675466SDimitry Andric /// Emit the Clang version as llvm.ident metadata. 1825bfef3995SDimitry Andric void EmitVersionIdentMetadata(); 1826bfef3995SDimitry Andric 1827676fbe81SDimitry Andric /// Emit the Clang commandline as llvm.commandline metadata. 1828676fbe81SDimitry Andric void EmitCommandLineMetadata(); 1829676fbe81SDimitry Andric 1830cfca06d7SDimitry Andric /// Emit the module flag metadata used to pass options controlling the 1831cfca06d7SDimitry Andric /// the backend to LLVM. 18327fa27ce4SDimitry Andric void EmitBackendOptionsMetadata(const CodeGenOptions &CodeGenOpts); 18339f4dbff6SDimitry Andric 1834ef915aabSDimitry Andric /// Emits OpenCL specific Metadata e.g. OpenCL version. 1835ef915aabSDimitry Andric void EmitOpenCLMetadata(); 1836ef915aabSDimitry Andric 18379f4dbff6SDimitry Andric /// Emit the llvm.gcov metadata used to tell LLVM where to emit the .gcno and 18389f4dbff6SDimitry Andric /// .gcda files in a way that persists in .bc files. 183929cafa66SDimitry Andric void EmitCoverageFile(); 184029cafa66SDimitry Andric 184106d4ba38SDimitry Andric /// Determine whether the definition must be emitted; if this returns \c 184206d4ba38SDimitry Andric /// false, the definition can be emitted lazily if it's used. 184306d4ba38SDimitry Andric bool MustBeEmitted(const ValueDecl *D); 184406d4ba38SDimitry Andric 184506d4ba38SDimitry Andric /// Determine whether the definition can be emitted eagerly, or should be 184606d4ba38SDimitry Andric /// delayed until the end of the translation unit. This is relevant for 184706d4ba38SDimitry Andric /// definitions whose linkage can change, e.g. implicit function instantions 184806d4ba38SDimitry Andric /// which may later be explicitly instantiated. 184906d4ba38SDimitry Andric bool MayBeEmittedEagerly(const ValueDecl *D); 1850bca07a45SDimitry Andric 18519f4dbff6SDimitry Andric /// Check whether we can use a "simpler", more core exceptions personality 18529f4dbff6SDimitry Andric /// function. 1853bca07a45SDimitry Andric void SimplifyPersonality(); 18547442d6faSDimitry Andric 18557fa27ce4SDimitry Andric /// Helper function for getDefaultFunctionAttributes. Builds a set of function 18567fa27ce4SDimitry Andric /// attributes which can be simply added to a function. 18577fa27ce4SDimitry Andric void getTrivialDefaultFunctionAttributes(StringRef Name, bool HasOptnone, 18587fa27ce4SDimitry Andric bool AttrOnCallSite, 18597fa27ce4SDimitry Andric llvm::AttrBuilder &FuncAttrs); 18607fa27ce4SDimitry Andric 1861cfca06d7SDimitry Andric /// Helper function for ConstructAttributeList and 1862cfca06d7SDimitry Andric /// addDefaultFunctionDefinitionAttributes. Builds a set of function 1863cfca06d7SDimitry Andric /// attributes to add to a function with the given properties. 1864cfca06d7SDimitry Andric void getDefaultFunctionAttributes(StringRef Name, bool HasOptnone, 18657442d6faSDimitry Andric bool AttrOnCallSite, 18667442d6faSDimitry Andric llvm::AttrBuilder &FuncAttrs); 186748675466SDimitry Andric 186848675466SDimitry Andric llvm::Metadata *CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map, 186948675466SDimitry Andric StringRef Suffix); 1870ec2b103cSEd Schouten }; 1871461a67faSDimitry Andric 1872ec2b103cSEd Schouten } // end namespace CodeGen 1873ec2b103cSEd Schouten } // end namespace clang 1874ec2b103cSEd Schouten 187545b53394SDimitry Andric #endif // LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H 1876