10b57cec5SDimitry Andric //===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This is the internal per-translation-unit state used for llvm translation. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "CGVTables.h" 170b57cec5SDimitry Andric #include "CodeGenTypeCache.h" 180b57cec5SDimitry Andric #include "CodeGenTypes.h" 190b57cec5SDimitry Andric #include "SanitizerMetadata.h" 200b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 210b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h" 220b57cec5SDimitry Andric #include "clang/AST/DeclOpenMP.h" 230b57cec5SDimitry Andric #include "clang/AST/GlobalDecl.h" 240b57cec5SDimitry Andric #include "clang/AST/Mangle.h" 250b57cec5SDimitry Andric #include "clang/Basic/ABI.h" 260b57cec5SDimitry Andric #include "clang/Basic/LangOptions.h" 27fe6060f1SDimitry Andric #include "clang/Basic/NoSanitizeList.h" 285f757f3fSDimitry Andric #include "clang/Basic/ProfileList.h" 295ffd83dbSDimitry Andric #include "clang/Basic/TargetInfo.h" 300b57cec5SDimitry Andric #include "clang/Basic/XRayLists.h" 31fe6060f1SDimitry Andric #include "clang/Lex/PreprocessorOptions.h" 320b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 3306c3fb27SDimitry Andric #include "llvm/ADT/MapVector.h" 340b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 350b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 360b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h" 370b57cec5SDimitry Andric #include "llvm/IR/Module.h" 380b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h" 390b57cec5SDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h" 40bdd1243dSDimitry Andric #include <optional> 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric namespace llvm { 430b57cec5SDimitry Andric class Module; 440b57cec5SDimitry Andric class Constant; 450b57cec5SDimitry Andric class ConstantInt; 460b57cec5SDimitry Andric class Function; 470b57cec5SDimitry Andric class GlobalValue; 480b57cec5SDimitry Andric class DataLayout; 490b57cec5SDimitry Andric class FunctionType; 500b57cec5SDimitry Andric class LLVMContext; 510b57cec5SDimitry Andric class IndexedInstrProfReader; 52972a253aSDimitry Andric 53972a253aSDimitry Andric namespace vfs { 54972a253aSDimitry Andric class FileSystem; 55972a253aSDimitry Andric } 560b57cec5SDimitry Andric } 570b57cec5SDimitry Andric 580b57cec5SDimitry Andric namespace clang { 590b57cec5SDimitry Andric class ASTContext; 600b57cec5SDimitry Andric class AtomicType; 610b57cec5SDimitry Andric class FunctionDecl; 620b57cec5SDimitry Andric class IdentifierInfo; 630b57cec5SDimitry Andric class ObjCImplementationDecl; 640b57cec5SDimitry Andric class ObjCEncodeExpr; 650b57cec5SDimitry Andric class BlockExpr; 660b57cec5SDimitry Andric class CharUnits; 670b57cec5SDimitry Andric class Decl; 680b57cec5SDimitry Andric class Expr; 690b57cec5SDimitry Andric class Stmt; 700b57cec5SDimitry Andric class StringLiteral; 710b57cec5SDimitry Andric class NamedDecl; 720fca6ea1SDimitry Andric class PointerAuthSchema; 730b57cec5SDimitry Andric class ValueDecl; 740b57cec5SDimitry Andric class VarDecl; 750b57cec5SDimitry Andric class LangOptions; 760b57cec5SDimitry Andric class CodeGenOptions; 770b57cec5SDimitry Andric class HeaderSearchOptions; 780b57cec5SDimitry Andric class DiagnosticsEngine; 790b57cec5SDimitry Andric class AnnotateAttr; 800b57cec5SDimitry Andric class CXXDestructorDecl; 810b57cec5SDimitry Andric class Module; 820b57cec5SDimitry Andric class CoverageSourceInfo; 83480093f4SDimitry Andric class InitSegAttr; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric namespace CodeGen { 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric class CodeGenFunction; 880b57cec5SDimitry Andric class CodeGenTBAA; 890b57cec5SDimitry Andric class CGCXXABI; 900b57cec5SDimitry Andric class CGDebugInfo; 910b57cec5SDimitry Andric class CGObjCRuntime; 920b57cec5SDimitry Andric class CGOpenCLRuntime; 930b57cec5SDimitry Andric class CGOpenMPRuntime; 940b57cec5SDimitry Andric class CGCUDARuntime; 9581ad6265SDimitry Andric class CGHLSLRuntime; 960b57cec5SDimitry Andric class CoverageMappingModuleGen; 970b57cec5SDimitry Andric class TargetCodeGenInfo; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric enum ForDefinition_t : bool { 1000b57cec5SDimitry Andric NotForDefinition = false, 1010b57cec5SDimitry Andric ForDefinition = true 1020b57cec5SDimitry Andric }; 1030b57cec5SDimitry Andric 104fe6060f1SDimitry Andric struct OrderGlobalInitsOrStermFinalizers { 1050b57cec5SDimitry Andric unsigned int priority; 1060b57cec5SDimitry Andric unsigned int lex_order; 107fe6060f1SDimitry Andric OrderGlobalInitsOrStermFinalizers(unsigned int p, unsigned int l) 1080b57cec5SDimitry Andric : priority(p), lex_order(l) {} 1090b57cec5SDimitry Andric 110fe6060f1SDimitry Andric bool operator==(const OrderGlobalInitsOrStermFinalizers &RHS) const { 1110b57cec5SDimitry Andric return priority == RHS.priority && lex_order == RHS.lex_order; 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 114fe6060f1SDimitry Andric bool operator<(const OrderGlobalInitsOrStermFinalizers &RHS) const { 1150b57cec5SDimitry Andric return std::tie(priority, lex_order) < 1160b57cec5SDimitry Andric std::tie(RHS.priority, RHS.lex_order); 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric }; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric struct ObjCEntrypoints { 1210b57cec5SDimitry Andric ObjCEntrypoints() { memset(this, 0, sizeof(*this)); } 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric /// void objc_alloc(id); 1240b57cec5SDimitry Andric llvm::FunctionCallee objc_alloc; 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric /// void objc_allocWithZone(id); 1270b57cec5SDimitry Andric llvm::FunctionCallee objc_allocWithZone; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric /// void objc_alloc_init(id); 1300b57cec5SDimitry Andric llvm::FunctionCallee objc_alloc_init; 1310b57cec5SDimitry Andric 1320b57cec5SDimitry Andric /// void objc_autoreleasePoolPop(void*); 1330b57cec5SDimitry Andric llvm::FunctionCallee objc_autoreleasePoolPop; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric /// void objc_autoreleasePoolPop(void*); 1360b57cec5SDimitry Andric /// Note this method is used when we are using exception handling 1370b57cec5SDimitry Andric llvm::FunctionCallee objc_autoreleasePoolPopInvoke; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric /// void *objc_autoreleasePoolPush(void); 1400b57cec5SDimitry Andric llvm::Function *objc_autoreleasePoolPush; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric /// id objc_autorelease(id); 1430b57cec5SDimitry Andric llvm::Function *objc_autorelease; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric /// id objc_autorelease(id); 1460b57cec5SDimitry Andric /// Note this is the runtime method not the intrinsic. 1470b57cec5SDimitry Andric llvm::FunctionCallee objc_autoreleaseRuntimeFunction; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric /// id objc_autoreleaseReturnValue(id); 1500b57cec5SDimitry Andric llvm::Function *objc_autoreleaseReturnValue; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric /// void objc_copyWeak(id *dest, id *src); 1530b57cec5SDimitry Andric llvm::Function *objc_copyWeak; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric /// void objc_destroyWeak(id*); 1560b57cec5SDimitry Andric llvm::Function *objc_destroyWeak; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric /// id objc_initWeak(id*, id); 1590b57cec5SDimitry Andric llvm::Function *objc_initWeak; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric /// id objc_loadWeak(id*); 1620b57cec5SDimitry Andric llvm::Function *objc_loadWeak; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric /// id objc_loadWeakRetained(id*); 1650b57cec5SDimitry Andric llvm::Function *objc_loadWeakRetained; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric /// void objc_moveWeak(id *dest, id *src); 1680b57cec5SDimitry Andric llvm::Function *objc_moveWeak; 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric /// id objc_retain(id); 1710b57cec5SDimitry Andric llvm::Function *objc_retain; 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric /// id objc_retain(id); 1740b57cec5SDimitry Andric /// Note this is the runtime method not the intrinsic. 1750b57cec5SDimitry Andric llvm::FunctionCallee objc_retainRuntimeFunction; 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric /// id objc_retainAutorelease(id); 1780b57cec5SDimitry Andric llvm::Function *objc_retainAutorelease; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric /// id objc_retainAutoreleaseReturnValue(id); 1810b57cec5SDimitry Andric llvm::Function *objc_retainAutoreleaseReturnValue; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric /// id objc_retainAutoreleasedReturnValue(id); 1840b57cec5SDimitry Andric llvm::Function *objc_retainAutoreleasedReturnValue; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric /// id objc_retainBlock(id); 1870b57cec5SDimitry Andric llvm::Function *objc_retainBlock; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric /// void objc_release(id); 1900b57cec5SDimitry Andric llvm::Function *objc_release; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric /// void objc_release(id); 1930b57cec5SDimitry Andric /// Note this is the runtime method not the intrinsic. 1940b57cec5SDimitry Andric llvm::FunctionCallee objc_releaseRuntimeFunction; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric /// void objc_storeStrong(id*, id); 1970b57cec5SDimitry Andric llvm::Function *objc_storeStrong; 1980b57cec5SDimitry Andric 1990b57cec5SDimitry Andric /// id objc_storeWeak(id*, id); 2000b57cec5SDimitry Andric llvm::Function *objc_storeWeak; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric /// id objc_unsafeClaimAutoreleasedReturnValue(id); 2030b57cec5SDimitry Andric llvm::Function *objc_unsafeClaimAutoreleasedReturnValue; 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric /// A void(void) inline asm to use to mark that the return value of 2060b57cec5SDimitry Andric /// a call will be immediately retain. 2070b57cec5SDimitry Andric llvm::InlineAsm *retainAutoreleasedReturnValueMarker; 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric /// void clang.arc.use(...); 2100b57cec5SDimitry Andric llvm::Function *clang_arc_use; 211fe6060f1SDimitry Andric 212fe6060f1SDimitry Andric /// void clang.arc.noop.use(...); 213fe6060f1SDimitry Andric llvm::Function *clang_arc_noop_use; 2140b57cec5SDimitry Andric }; 2150b57cec5SDimitry Andric 2160b57cec5SDimitry Andric /// This class records statistics on instrumentation based profiling. 2170b57cec5SDimitry Andric class InstrProfStats { 2185f757f3fSDimitry Andric uint32_t VisitedInMainFile = 0; 2195f757f3fSDimitry Andric uint32_t MissingInMainFile = 0; 2205f757f3fSDimitry Andric uint32_t Visited = 0; 2215f757f3fSDimitry Andric uint32_t Missing = 0; 2225f757f3fSDimitry Andric uint32_t Mismatched = 0; 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric public: 2255f757f3fSDimitry Andric InstrProfStats() = default; 2260b57cec5SDimitry Andric /// Record that we've visited a function and whether or not that function was 2270b57cec5SDimitry Andric /// in the main source file. 2280b57cec5SDimitry Andric void addVisited(bool MainFile) { 2290b57cec5SDimitry Andric if (MainFile) 2300b57cec5SDimitry Andric ++VisitedInMainFile; 2310b57cec5SDimitry Andric ++Visited; 2320b57cec5SDimitry Andric } 2330b57cec5SDimitry Andric /// Record that a function we've visited has no profile data. 2340b57cec5SDimitry Andric void addMissing(bool MainFile) { 2350b57cec5SDimitry Andric if (MainFile) 2360b57cec5SDimitry Andric ++MissingInMainFile; 2370b57cec5SDimitry Andric ++Missing; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric /// Record that a function we've visited has mismatched profile data. 2400b57cec5SDimitry Andric void addMismatched(bool MainFile) { ++Mismatched; } 2410b57cec5SDimitry Andric /// Whether or not the stats we've gathered indicate any potential problems. 2420b57cec5SDimitry Andric bool hasDiagnostics() { return Missing || Mismatched; } 2430b57cec5SDimitry Andric /// Report potential problems we've found to \c Diags. 2440b57cec5SDimitry Andric void reportDiagnostics(DiagnosticsEngine &Diags, StringRef MainFile); 2450b57cec5SDimitry Andric }; 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric /// A pair of helper functions for a __block variable. 2480b57cec5SDimitry Andric class BlockByrefHelpers : public llvm::FoldingSetNode { 2490b57cec5SDimitry Andric // MSVC requires this type to be complete in order to process this 2500b57cec5SDimitry Andric // header. 2510b57cec5SDimitry Andric public: 2520b57cec5SDimitry Andric llvm::Constant *CopyHelper; 2530b57cec5SDimitry Andric llvm::Constant *DisposeHelper; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric /// The alignment of the field. This is important because 2560b57cec5SDimitry Andric /// different offsets to the field within the byref struct need to 2570b57cec5SDimitry Andric /// have different helper functions. 2580b57cec5SDimitry Andric CharUnits Alignment; 2590b57cec5SDimitry Andric 2600b57cec5SDimitry Andric BlockByrefHelpers(CharUnits alignment) 2610b57cec5SDimitry Andric : CopyHelper(nullptr), DisposeHelper(nullptr), Alignment(alignment) {} 2620b57cec5SDimitry Andric BlockByrefHelpers(const BlockByrefHelpers &) = default; 2630b57cec5SDimitry Andric virtual ~BlockByrefHelpers(); 2640b57cec5SDimitry Andric 2650b57cec5SDimitry Andric void Profile(llvm::FoldingSetNodeID &id) const { 2660b57cec5SDimitry Andric id.AddInteger(Alignment.getQuantity()); 2670b57cec5SDimitry Andric profileImpl(id); 2680b57cec5SDimitry Andric } 2690b57cec5SDimitry Andric virtual void profileImpl(llvm::FoldingSetNodeID &id) const = 0; 2700b57cec5SDimitry Andric 2710b57cec5SDimitry Andric virtual bool needsCopy() const { return true; } 2720b57cec5SDimitry Andric virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src) = 0; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric virtual bool needsDispose() const { return true; } 2750b57cec5SDimitry Andric virtual void emitDispose(CodeGenFunction &CGF, Address field) = 0; 2760b57cec5SDimitry Andric }; 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric /// This class organizes the cross-function state that is used while generating 2790b57cec5SDimitry Andric /// LLVM code. 2800b57cec5SDimitry Andric class CodeGenModule : public CodeGenTypeCache { 2810b57cec5SDimitry Andric CodeGenModule(const CodeGenModule &) = delete; 2820b57cec5SDimitry Andric void operator=(const CodeGenModule &) = delete; 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric public: 2850b57cec5SDimitry Andric struct Structor { 286bdd1243dSDimitry Andric Structor() 287bdd1243dSDimitry Andric : Priority(0), LexOrder(~0u), Initializer(nullptr), 288bdd1243dSDimitry Andric AssociatedData(nullptr) {} 289bdd1243dSDimitry Andric Structor(int Priority, unsigned LexOrder, llvm::Constant *Initializer, 2900b57cec5SDimitry Andric llvm::Constant *AssociatedData) 291bdd1243dSDimitry Andric : Priority(Priority), LexOrder(LexOrder), Initializer(Initializer), 2920b57cec5SDimitry Andric AssociatedData(AssociatedData) {} 2930b57cec5SDimitry Andric int Priority; 294bdd1243dSDimitry Andric unsigned LexOrder; 2950b57cec5SDimitry Andric llvm::Constant *Initializer; 2960b57cec5SDimitry Andric llvm::Constant *AssociatedData; 2970b57cec5SDimitry Andric }; 2980b57cec5SDimitry Andric 2990b57cec5SDimitry Andric typedef std::vector<Structor> CtorList; 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric private: 3020b57cec5SDimitry Andric ASTContext &Context; 3030b57cec5SDimitry Andric const LangOptions &LangOpts; 304972a253aSDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; // Only used for debug info. 3050b57cec5SDimitry Andric const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info. 3060b57cec5SDimitry Andric const PreprocessorOptions &PreprocessorOpts; // Only used for debug info. 3070b57cec5SDimitry Andric const CodeGenOptions &CodeGenOpts; 3085ffd83dbSDimitry Andric unsigned NumAutoVarInit = 0; 3090b57cec5SDimitry Andric llvm::Module &TheModule; 3100b57cec5SDimitry Andric DiagnosticsEngine &Diags; 3110b57cec5SDimitry Andric const TargetInfo &Target; 3120b57cec5SDimitry Andric std::unique_ptr<CGCXXABI> ABI; 3130b57cec5SDimitry Andric llvm::LLVMContext &VMContext; 31404eeddc0SDimitry Andric std::string ModuleNameHash; 315fcaf7f86SDimitry Andric bool CXX20ModuleInits = false; 3160b57cec5SDimitry Andric std::unique_ptr<CodeGenTBAA> TBAA; 3170b57cec5SDimitry Andric 3180b57cec5SDimitry Andric mutable std::unique_ptr<TargetCodeGenInfo> TheTargetCodeGenInfo; 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric // This should not be moved earlier, since its initialization depends on some 3210b57cec5SDimitry Andric // of the previous reference members being already initialized and also checks 3220b57cec5SDimitry Andric // if TheTargetCodeGenInfo is NULL 323*5deeebd8SDimitry Andric std::unique_ptr<CodeGenTypes> Types; 3240b57cec5SDimitry Andric 3250b57cec5SDimitry Andric /// Holds information about C++ vtables. 3260b57cec5SDimitry Andric CodeGenVTables VTables; 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric std::unique_ptr<CGObjCRuntime> ObjCRuntime; 3290b57cec5SDimitry Andric std::unique_ptr<CGOpenCLRuntime> OpenCLRuntime; 3300b57cec5SDimitry Andric std::unique_ptr<CGOpenMPRuntime> OpenMPRuntime; 3310b57cec5SDimitry Andric std::unique_ptr<CGCUDARuntime> CUDARuntime; 33281ad6265SDimitry Andric std::unique_ptr<CGHLSLRuntime> HLSLRuntime; 3330b57cec5SDimitry Andric std::unique_ptr<CGDebugInfo> DebugInfo; 3340b57cec5SDimitry Andric std::unique_ptr<ObjCEntrypoints> ObjCData; 3350b57cec5SDimitry Andric llvm::MDNode *NoObjCARCExceptionsMetadata = nullptr; 3360b57cec5SDimitry Andric std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader; 3370b57cec5SDimitry Andric InstrProfStats PGOStats; 3380b57cec5SDimitry Andric std::unique_ptr<llvm::SanitizerStatReport> SanStats; 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric // A set of references that have only been seen via a weakref so far. This is 3410b57cec5SDimitry Andric // used to remove the weak of the reference if we ever see a direct reference 3420b57cec5SDimitry Andric // or a definition. 3430b57cec5SDimitry Andric llvm::SmallPtrSet<llvm::GlobalValue*, 10> WeakRefReferences; 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andric /// This contains all the decls which have definitions but/ which are deferred 3460b57cec5SDimitry Andric /// for emission and therefore should only be output if they are actually 3470b57cec5SDimitry Andric /// used. If a decl is in this, then it is known to have not been referenced 3480b57cec5SDimitry Andric /// yet. 34904eeddc0SDimitry Andric llvm::DenseMap<StringRef, GlobalDecl> DeferredDecls; 3500b57cec5SDimitry Andric 3510fca6ea1SDimitry Andric llvm::StringSet<llvm::BumpPtrAllocator> DeferredResolversToEmit; 3520fca6ea1SDimitry Andric 3530b57cec5SDimitry Andric /// This is a list of deferred decls which we have seen that *are* actually 3540b57cec5SDimitry Andric /// referenced. These get code generated when the module is done. 3550b57cec5SDimitry Andric std::vector<GlobalDecl> DeferredDeclsToEmit; 3560b57cec5SDimitry Andric void addDeferredDeclToEmit(GlobalDecl GD) { 3570b57cec5SDimitry Andric DeferredDeclsToEmit.emplace_back(GD); 358753f127fSDimitry Andric addEmittedDeferredDecl(GD); 359753f127fSDimitry Andric } 360753f127fSDimitry Andric 361753f127fSDimitry Andric /// Decls that were DeferredDecls and have now been emitted. 362753f127fSDimitry Andric llvm::DenseMap<llvm::StringRef, GlobalDecl> EmittedDeferredDecls; 363753f127fSDimitry Andric 364753f127fSDimitry Andric void addEmittedDeferredDecl(GlobalDecl GD) { 3658a4dda33SDimitry Andric // Reemission is only needed in incremental mode. 3668a4dda33SDimitry Andric if (!Context.getLangOpts().IncrementalExtensions) 367753f127fSDimitry Andric return; 3688a4dda33SDimitry Andric 3698a4dda33SDimitry Andric // Assume a linkage by default that does not need reemission. 3708a4dda33SDimitry Andric auto L = llvm::GlobalValue::ExternalLinkage; 3718a4dda33SDimitry Andric if (llvm::isa<FunctionDecl>(GD.getDecl())) 3728a4dda33SDimitry Andric L = getFunctionLinkage(GD); 3738a4dda33SDimitry Andric else if (auto *VD = llvm::dyn_cast<VarDecl>(GD.getDecl())) 3748a4dda33SDimitry Andric L = getLLVMLinkageVarDefinition(VD); 3758a4dda33SDimitry Andric 3768a4dda33SDimitry Andric if (llvm::GlobalValue::isInternalLinkage(L) || 3778a4dda33SDimitry Andric llvm::GlobalValue::isLinkOnceLinkage(L) || 378753f127fSDimitry Andric llvm::GlobalValue::isWeakLinkage(L)) { 379753f127fSDimitry Andric EmittedDeferredDecls[getMangledName(GD)] = GD; 380753f127fSDimitry Andric } 3810b57cec5SDimitry Andric } 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric /// List of alias we have emitted. Used to make sure that what they point to 3840b57cec5SDimitry Andric /// is defined once we get to the end of the of the translation unit. 3850b57cec5SDimitry Andric std::vector<GlobalDecl> Aliases; 3860b57cec5SDimitry Andric 38781ad6265SDimitry Andric /// List of multiversion functions to be emitted. This list is processed in 38881ad6265SDimitry Andric /// conjunction with other deferred symbols and is used to ensure that 38981ad6265SDimitry Andric /// multiversion function resolvers and ifuncs are defined and emitted. 3900b57cec5SDimitry Andric std::vector<GlobalDecl> MultiVersionFuncs; 3910b57cec5SDimitry Andric 39206c3fb27SDimitry Andric llvm::MapVector<StringRef, llvm::TrackingVH<llvm::Constant>> Replacements; 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric /// List of global values to be replaced with something else. Used when we 3950b57cec5SDimitry Andric /// want to replace a GlobalValue but can't identify it by its mangled name 3960b57cec5SDimitry Andric /// anymore (because the name is already taken). 3970b57cec5SDimitry Andric llvm::SmallVector<std::pair<llvm::GlobalValue *, llvm::Constant *>, 8> 3980b57cec5SDimitry Andric GlobalValReplacements; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric /// Variables for which we've emitted globals containing their constant 4010b57cec5SDimitry Andric /// values along with the corresponding globals, for opportunistic reuse. 4020b57cec5SDimitry Andric llvm::DenseMap<const VarDecl*, llvm::GlobalVariable*> InitializerConstants; 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric /// Set of global decls for which we already diagnosed mangled name conflict. 4050b57cec5SDimitry Andric /// Required to not issue a warning (on a mangling conflict) multiple times 4060b57cec5SDimitry Andric /// for the same decl. 4070b57cec5SDimitry Andric llvm::DenseSet<GlobalDecl> DiagnosedConflictingDefinitions; 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric /// A queue of (optional) vtables to consider emitting. 4100b57cec5SDimitry Andric std::vector<const CXXRecordDecl*> DeferredVTables; 4110b57cec5SDimitry Andric 4120b57cec5SDimitry Andric /// A queue of (optional) vtables that may be emitted opportunistically. 4130b57cec5SDimitry Andric std::vector<const CXXRecordDecl *> OpportunisticVTables; 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric /// List of global values which are required to be present in the object file; 4160b57cec5SDimitry Andric /// bitcast to i8*. This is used for forcing visibility of symbols which may 4170b57cec5SDimitry Andric /// otherwise be optimized out. 4180b57cec5SDimitry Andric std::vector<llvm::WeakTrackingVH> LLVMUsed; 4190b57cec5SDimitry Andric std::vector<llvm::WeakTrackingVH> LLVMCompilerUsed; 4200b57cec5SDimitry Andric 4210b57cec5SDimitry Andric /// Store the list of global constructors and their respective priorities to 4220b57cec5SDimitry Andric /// be emitted when the translation unit is complete. 4230b57cec5SDimitry Andric CtorList GlobalCtors; 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric /// Store the list of global destructors and their respective priorities to be 4260b57cec5SDimitry Andric /// emitted when the translation unit is complete. 4270b57cec5SDimitry Andric CtorList GlobalDtors; 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric /// An ordered map of canonical GlobalDecls to their mangled names. 4300b57cec5SDimitry Andric llvm::MapVector<GlobalDecl, StringRef> MangledDeclNames; 4310b57cec5SDimitry Andric llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings; 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric /// Global annotations. 4340b57cec5SDimitry Andric std::vector<llvm::Constant*> Annotations; 4350b57cec5SDimitry Andric 4365f757f3fSDimitry Andric // Store deferred function annotations so they can be emitted at the end with 4375f757f3fSDimitry Andric // most up to date ValueDecl that will have all the inherited annotations. 4380fca6ea1SDimitry Andric llvm::MapVector<StringRef, const ValueDecl *> DeferredAnnotations; 4395f757f3fSDimitry Andric 4400b57cec5SDimitry Andric /// Map used to get unique annotation strings. 4410b57cec5SDimitry Andric llvm::StringMap<llvm::Constant*> AnnotationStrings; 4420b57cec5SDimitry Andric 443e8d8bef9SDimitry Andric /// Used for uniquing of annotation arguments. 444e8d8bef9SDimitry Andric llvm::DenseMap<unsigned, llvm::Constant *> AnnotationArgs; 445e8d8bef9SDimitry Andric 4460b57cec5SDimitry Andric llvm::StringMap<llvm::GlobalVariable *> CFConstantStringMap; 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> ConstantStringMap; 44981ad6265SDimitry Andric llvm::DenseMap<const UnnamedGlobalConstantDecl *, llvm::GlobalVariable *> 45081ad6265SDimitry Andric UnnamedGlobalConstantDeclMap; 4510b57cec5SDimitry Andric llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap; 4520b57cec5SDimitry Andric llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap; 4530b57cec5SDimitry Andric llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap; 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap; 4560b57cec5SDimitry Andric llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric /// Map used to get unique type descriptor constants for sanitizers. 4590b57cec5SDimitry Andric llvm::DenseMap<QualType, llvm::Constant *> TypeDescriptorMap; 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric /// Map used to track internal linkage functions declared within 4620b57cec5SDimitry Andric /// extern "C" regions. 4630b57cec5SDimitry Andric typedef llvm::MapVector<IdentifierInfo *, 4640b57cec5SDimitry Andric llvm::GlobalValue *> StaticExternCMap; 4650b57cec5SDimitry Andric StaticExternCMap StaticExternCValues; 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric /// thread_local variables defined or used in this TU. 4680b57cec5SDimitry Andric std::vector<const VarDecl *> CXXThreadLocals; 4690b57cec5SDimitry Andric 4700b57cec5SDimitry Andric /// thread_local variables with initializers that need to run 4710b57cec5SDimitry Andric /// before any thread_local variable in this TU is odr-used. 4720b57cec5SDimitry Andric std::vector<llvm::Function *> CXXThreadLocalInits; 4730b57cec5SDimitry Andric std::vector<const VarDecl *> CXXThreadLocalInitVars; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric /// Global variables with initializers that need to run before main. 4760b57cec5SDimitry Andric std::vector<llvm::Function *> CXXGlobalInits; 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric /// When a C++ decl with an initializer is deferred, null is 4790b57cec5SDimitry Andric /// appended to CXXGlobalInits, and the index of that null is placed 4800b57cec5SDimitry Andric /// here so that the initializer will be performed in the correct 4810b57cec5SDimitry Andric /// order. Once the decl is emitted, the index is replaced with ~0U to ensure 4820b57cec5SDimitry Andric /// that we don't re-emit the initializer. 4830b57cec5SDimitry Andric llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition; 4840b57cec5SDimitry Andric 485fe6060f1SDimitry Andric typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *> 486fe6060f1SDimitry Andric GlobalInitData; 4870b57cec5SDimitry Andric 4880fca6ea1SDimitry Andric // When a tail call is performed on an "undefined" symbol, on PPC without pc 4890fca6ea1SDimitry Andric // relative feature, the tail call is not allowed. In "EmitCall" for such 4900fca6ea1SDimitry Andric // tail calls, the "undefined" symbols may be forward declarations, their 4910fca6ea1SDimitry Andric // definitions are provided in the module after the callsites. For such tail 4920fca6ea1SDimitry Andric // calls, diagnose message should not be emitted. 4930fca6ea1SDimitry Andric llvm::SmallSetVector<std::pair<const FunctionDecl *, SourceLocation>, 4> 4940fca6ea1SDimitry Andric MustTailCallUndefinedGlobals; 4950fca6ea1SDimitry Andric 4960b57cec5SDimitry Andric struct GlobalInitPriorityCmp { 4970b57cec5SDimitry Andric bool operator()(const GlobalInitData &LHS, 4980b57cec5SDimitry Andric const GlobalInitData &RHS) const { 4990b57cec5SDimitry Andric return LHS.first.priority < RHS.first.priority; 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric }; 5020b57cec5SDimitry Andric 5030b57cec5SDimitry Andric /// Global variables with initializers whose order of initialization is set by 5040b57cec5SDimitry Andric /// init_priority attribute. 5050b57cec5SDimitry Andric SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits; 5060b57cec5SDimitry Andric 5070b57cec5SDimitry Andric /// Global destructor functions and arguments that need to run on termination. 5085ffd83dbSDimitry Andric /// When UseSinitAndSterm is set, it instead contains sterm finalizer 5095ffd83dbSDimitry Andric /// functions, which also run on unloading a shared library. 510fe6060f1SDimitry Andric typedef std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, 511fe6060f1SDimitry Andric llvm::Constant *> 512fe6060f1SDimitry Andric CXXGlobalDtorsOrStermFinalizer_t; 513fe6060f1SDimitry Andric SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> 5145ffd83dbSDimitry Andric CXXGlobalDtorsOrStermFinalizers; 5150b57cec5SDimitry Andric 516fe6060f1SDimitry Andric typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *> 517fe6060f1SDimitry Andric StermFinalizerData; 518fe6060f1SDimitry Andric 519fe6060f1SDimitry Andric struct StermFinalizerPriorityCmp { 520fe6060f1SDimitry Andric bool operator()(const StermFinalizerData &LHS, 521fe6060f1SDimitry Andric const StermFinalizerData &RHS) const { 522fe6060f1SDimitry Andric return LHS.first.priority < RHS.first.priority; 523fe6060f1SDimitry Andric } 524fe6060f1SDimitry Andric }; 525fe6060f1SDimitry Andric 526fe6060f1SDimitry Andric /// Global variables with sterm finalizers whose order of initialization is 527fe6060f1SDimitry Andric /// set by init_priority attribute. 528fe6060f1SDimitry Andric SmallVector<StermFinalizerData, 8> PrioritizedCXXStermFinalizers; 529fe6060f1SDimitry Andric 5300b57cec5SDimitry Andric /// The complete set of modules that has been imported. 5310b57cec5SDimitry Andric llvm::SetVector<clang::Module *> ImportedModules; 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric /// The set of modules for which the module initializers 5340b57cec5SDimitry Andric /// have been emitted. 5350b57cec5SDimitry Andric llvm::SmallPtrSet<clang::Module *, 16> EmittedModuleInitializers; 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric /// A vector of metadata strings for linker options. 5380b57cec5SDimitry Andric SmallVector<llvm::MDNode *, 16> LinkerOptionsMetadata; 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric /// A vector of metadata strings for dependent libraries for ELF. 5410b57cec5SDimitry Andric SmallVector<llvm::MDNode *, 16> ELFDependentLibraries; 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric /// @name Cache for Objective-C runtime types 5440b57cec5SDimitry Andric /// @{ 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric /// Cached reference to the class for constant strings. This value has type 5470b57cec5SDimitry Andric /// int * but is actually an Obj-C class pointer. 5480b57cec5SDimitry Andric llvm::WeakTrackingVH CFConstantStringClassRef; 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric /// The type used to describe the state of a fast enumeration in 5510b57cec5SDimitry Andric /// Objective-C's for..in loop. 5520b57cec5SDimitry Andric QualType ObjCFastEnumerationStateType; 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric /// @} 5550b57cec5SDimitry Andric 5560b57cec5SDimitry Andric /// Lazily create the Objective-C runtime 5570b57cec5SDimitry Andric void createObjCRuntime(); 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric void createOpenCLRuntime(); 5600b57cec5SDimitry Andric void createOpenMPRuntime(); 5610b57cec5SDimitry Andric void createCUDARuntime(); 56281ad6265SDimitry Andric void createHLSLRuntime(); 5630b57cec5SDimitry Andric 5640b57cec5SDimitry Andric bool isTriviallyRecursive(const FunctionDecl *F); 5650b57cec5SDimitry Andric bool shouldEmitFunction(GlobalDecl GD); 5660fca6ea1SDimitry Andric // Whether a global variable should be emitted by CUDA/HIP host/device 5670fca6ea1SDimitry Andric // related attributes. 5680fca6ea1SDimitry Andric bool shouldEmitCUDAGlobalVar(const VarDecl *VD) const; 5690b57cec5SDimitry Andric bool shouldOpportunisticallyEmitVTables(); 5700b57cec5SDimitry Andric /// Map used to be sure we don't emit the same CompoundLiteral twice. 5710b57cec5SDimitry Andric llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *> 5720b57cec5SDimitry Andric EmittedCompoundLiterals; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric /// Map of the global blocks we've emitted, so that we don't have to re-emit 5750b57cec5SDimitry Andric /// them if the constexpr evaluator gets aggressive. 5760b57cec5SDimitry Andric llvm::DenseMap<const BlockExpr *, llvm::Constant *> EmittedGlobalBlocks; 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andric /// @name Cache for Blocks Runtime Globals 5790b57cec5SDimitry Andric /// @{ 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andric llvm::Constant *NSConcreteGlobalBlock = nullptr; 5820b57cec5SDimitry Andric llvm::Constant *NSConcreteStackBlock = nullptr; 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric llvm::FunctionCallee BlockObjectAssign = nullptr; 5850b57cec5SDimitry Andric llvm::FunctionCallee BlockObjectDispose = nullptr; 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric llvm::Type *BlockDescriptorType = nullptr; 5880b57cec5SDimitry Andric llvm::Type *GenericBlockLiteralType = nullptr; 5890b57cec5SDimitry Andric 5900b57cec5SDimitry Andric struct { 5910b57cec5SDimitry Andric int GlobalUniqueCount; 5920b57cec5SDimitry Andric } Block; 5930b57cec5SDimitry Andric 594480093f4SDimitry Andric GlobalDecl initializedGlobalDecl; 595480093f4SDimitry Andric 596480093f4SDimitry Andric /// @} 597480093f4SDimitry Andric 5980b57cec5SDimitry Andric /// void @llvm.lifetime.start(i64 %size, i8* nocapture <ptr>) 5990b57cec5SDimitry Andric llvm::Function *LifetimeStartFn = nullptr; 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric /// void @llvm.lifetime.end(i64 %size, i8* nocapture <ptr>) 6020b57cec5SDimitry Andric llvm::Function *LifetimeEndFn = nullptr; 6030b57cec5SDimitry Andric 6040b57cec5SDimitry Andric std::unique_ptr<SanitizerMetadata> SanitizerMD; 6050b57cec5SDimitry Andric 6060b57cec5SDimitry Andric llvm::MapVector<const Decl *, bool> DeferredEmptyCoverageMappingDecls; 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric std::unique_ptr<CoverageMappingModuleGen> CoverageMapping; 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric /// Mapping from canonical types to their metadata identifiers. We need to 6110b57cec5SDimitry Andric /// maintain this mapping because identifiers may be formed from distinct 6120b57cec5SDimitry Andric /// MDNodes. 6130b57cec5SDimitry Andric typedef llvm::DenseMap<QualType, llvm::Metadata *> MetadataTypeMap; 6140b57cec5SDimitry Andric MetadataTypeMap MetadataIdMap; 6150b57cec5SDimitry Andric MetadataTypeMap VirtualMetadataIdMap; 6160b57cec5SDimitry Andric MetadataTypeMap GeneralizedMetadataIdMap; 6170b57cec5SDimitry Andric 618bdd1243dSDimitry Andric // Helps squashing blocks of TopLevelStmtDecl into a single llvm::Function 619bdd1243dSDimitry Andric // when used with -fincremental-extensions. 620bdd1243dSDimitry Andric std::pair<std::unique_ptr<CodeGenFunction>, const TopLevelStmtDecl *> 621bdd1243dSDimitry Andric GlobalTopLevelStmtBlockInFlight; 622bdd1243dSDimitry Andric 6230fca6ea1SDimitry Andric llvm::DenseMap<GlobalDecl, uint16_t> PtrAuthDiscriminatorHashes; 6240fca6ea1SDimitry Andric 6250fca6ea1SDimitry Andric llvm::DenseMap<const CXXRecordDecl *, std::optional<PointerAuthQualifier>> 6260fca6ea1SDimitry Andric VTablePtrAuthInfos; 6270fca6ea1SDimitry Andric std::optional<PointerAuthQualifier> 6280fca6ea1SDimitry Andric computeVTPointerAuthentication(const CXXRecordDecl *ThisClass); 6290fca6ea1SDimitry Andric 6300b57cec5SDimitry Andric public: 631972a253aSDimitry Andric CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, 632972a253aSDimitry Andric const HeaderSearchOptions &headersearchopts, 6330b57cec5SDimitry Andric const PreprocessorOptions &ppopts, 6340b57cec5SDimitry Andric const CodeGenOptions &CodeGenOpts, llvm::Module &M, 6350b57cec5SDimitry Andric DiagnosticsEngine &Diags, 6360b57cec5SDimitry Andric CoverageSourceInfo *CoverageInfo = nullptr); 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric ~CodeGenModule(); 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric void clear(); 6410b57cec5SDimitry Andric 6420b57cec5SDimitry Andric /// Finalize LLVM code generation. 6430b57cec5SDimitry Andric void Release(); 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric /// Return true if we should emit location information for expressions. 6460b57cec5SDimitry Andric bool getExpressionLocationsEnabled() const; 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric /// Return a reference to the configured Objective-C runtime. 6490b57cec5SDimitry Andric CGObjCRuntime &getObjCRuntime() { 6500b57cec5SDimitry Andric if (!ObjCRuntime) createObjCRuntime(); 6510b57cec5SDimitry Andric return *ObjCRuntime; 6520b57cec5SDimitry Andric } 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric /// Return true iff an Objective-C runtime has been configured. 6550b57cec5SDimitry Andric bool hasObjCRuntime() { return !!ObjCRuntime; } 6560b57cec5SDimitry Andric 657fe6060f1SDimitry Andric const std::string &getModuleNameHash() const { return ModuleNameHash; } 658fe6060f1SDimitry Andric 6590b57cec5SDimitry Andric /// Return a reference to the configured OpenCL runtime. 6600b57cec5SDimitry Andric CGOpenCLRuntime &getOpenCLRuntime() { 6610b57cec5SDimitry Andric assert(OpenCLRuntime != nullptr); 6620b57cec5SDimitry Andric return *OpenCLRuntime; 6630b57cec5SDimitry Andric } 6640b57cec5SDimitry Andric 6650b57cec5SDimitry Andric /// Return a reference to the configured OpenMP runtime. 6660b57cec5SDimitry Andric CGOpenMPRuntime &getOpenMPRuntime() { 6670b57cec5SDimitry Andric assert(OpenMPRuntime != nullptr); 6680b57cec5SDimitry Andric return *OpenMPRuntime; 6690b57cec5SDimitry Andric } 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric /// Return a reference to the configured CUDA runtime. 6720b57cec5SDimitry Andric CGCUDARuntime &getCUDARuntime() { 6730b57cec5SDimitry Andric assert(CUDARuntime != nullptr); 6740b57cec5SDimitry Andric return *CUDARuntime; 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric 67781ad6265SDimitry Andric /// Return a reference to the configured HLSL runtime. 67881ad6265SDimitry Andric CGHLSLRuntime &getHLSLRuntime() { 67981ad6265SDimitry Andric assert(HLSLRuntime != nullptr); 68081ad6265SDimitry Andric return *HLSLRuntime; 68181ad6265SDimitry Andric } 68281ad6265SDimitry Andric 6830b57cec5SDimitry Andric ObjCEntrypoints &getObjCEntrypoints() const { 6840b57cec5SDimitry Andric assert(ObjCData != nullptr); 6850b57cec5SDimitry Andric return *ObjCData; 6860b57cec5SDimitry Andric } 6870b57cec5SDimitry Andric 688e8d8bef9SDimitry Andric // Version checking functions, used to implement ObjC's @available: 6890b57cec5SDimitry Andric // i32 @__isOSVersionAtLeast(i32, i32, i32) 6900b57cec5SDimitry Andric llvm::FunctionCallee IsOSVersionAtLeastFn = nullptr; 691e8d8bef9SDimitry Andric // i32 @__isPlatformVersionAtLeast(i32, i32, i32, i32) 692e8d8bef9SDimitry Andric llvm::FunctionCallee IsPlatformVersionAtLeastFn = nullptr; 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric InstrProfStats &getPGOStats() { return PGOStats; } 6950b57cec5SDimitry Andric llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); } 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric CoverageMappingModuleGen *getCoverageMapping() const { 6980b57cec5SDimitry Andric return CoverageMapping.get(); 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) { 7020b57cec5SDimitry Andric return StaticLocalDeclMap[D]; 7030b57cec5SDimitry Andric } 7040b57cec5SDimitry Andric void setStaticLocalDeclAddress(const VarDecl *D, 7050b57cec5SDimitry Andric llvm::Constant *C) { 7060b57cec5SDimitry Andric StaticLocalDeclMap[D] = C; 7070b57cec5SDimitry Andric } 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andric llvm::Constant * 7100b57cec5SDimitry Andric getOrCreateStaticVarDecl(const VarDecl &D, 7110b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage); 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric llvm::GlobalVariable *getStaticLocalDeclGuardAddress(const VarDecl *D) { 7140b57cec5SDimitry Andric return StaticLocalDeclGuardMap[D]; 7150b57cec5SDimitry Andric } 7160b57cec5SDimitry Andric void setStaticLocalDeclGuardAddress(const VarDecl *D, 7170b57cec5SDimitry Andric llvm::GlobalVariable *C) { 7180b57cec5SDimitry Andric StaticLocalDeclGuardMap[D] = C; 7190b57cec5SDimitry Andric } 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant, 7220b57cec5SDimitry Andric CharUnits Align); 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric bool lookupRepresentativeDecl(StringRef MangledName, 7250b57cec5SDimitry Andric GlobalDecl &Result) const; 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) { 7280b57cec5SDimitry Andric return AtomicSetterHelperFnMap[Ty]; 7290b57cec5SDimitry Andric } 7300b57cec5SDimitry Andric void setAtomicSetterHelperFnMap(QualType Ty, 7310b57cec5SDimitry Andric llvm::Constant *Fn) { 7320b57cec5SDimitry Andric AtomicSetterHelperFnMap[Ty] = Fn; 7330b57cec5SDimitry Andric } 7340b57cec5SDimitry Andric 7350b57cec5SDimitry Andric llvm::Constant *getAtomicGetterHelperFnMap(QualType Ty) { 7360b57cec5SDimitry Andric return AtomicGetterHelperFnMap[Ty]; 7370b57cec5SDimitry Andric } 7380b57cec5SDimitry Andric void setAtomicGetterHelperFnMap(QualType Ty, 7390b57cec5SDimitry Andric llvm::Constant *Fn) { 7400b57cec5SDimitry Andric AtomicGetterHelperFnMap[Ty] = Fn; 7410b57cec5SDimitry Andric } 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric llvm::Constant *getTypeDescriptorFromMap(QualType Ty) { 7440b57cec5SDimitry Andric return TypeDescriptorMap[Ty]; 7450b57cec5SDimitry Andric } 7460b57cec5SDimitry Andric void setTypeDescriptorInMap(QualType Ty, llvm::Constant *C) { 7470b57cec5SDimitry Andric TypeDescriptorMap[Ty] = C; 7480b57cec5SDimitry Andric } 7490b57cec5SDimitry Andric 7500b57cec5SDimitry Andric CGDebugInfo *getModuleDebugInfo() { return DebugInfo.get(); } 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric llvm::MDNode *getNoObjCARCExceptionsMetadata() { 7530b57cec5SDimitry Andric if (!NoObjCARCExceptionsMetadata) 754bdd1243dSDimitry Andric NoObjCARCExceptionsMetadata = 755bdd1243dSDimitry Andric llvm::MDNode::get(getLLVMContext(), std::nullopt); 7560b57cec5SDimitry Andric return NoObjCARCExceptionsMetadata; 7570b57cec5SDimitry Andric } 7580b57cec5SDimitry Andric 7590b57cec5SDimitry Andric ASTContext &getContext() const { return Context; } 7600b57cec5SDimitry Andric const LangOptions &getLangOpts() const { return LangOpts; } 761972a253aSDimitry Andric const IntrusiveRefCntPtr<llvm::vfs::FileSystem> &getFileSystem() const { 762972a253aSDimitry Andric return FS; 763972a253aSDimitry Andric } 7640b57cec5SDimitry Andric const HeaderSearchOptions &getHeaderSearchOpts() 7650b57cec5SDimitry Andric const { return HeaderSearchOpts; } 7660b57cec5SDimitry Andric const PreprocessorOptions &getPreprocessorOpts() 7670b57cec5SDimitry Andric const { return PreprocessorOpts; } 7680b57cec5SDimitry Andric const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; } 7690b57cec5SDimitry Andric llvm::Module &getModule() const { return TheModule; } 7700b57cec5SDimitry Andric DiagnosticsEngine &getDiags() const { return Diags; } 7710b57cec5SDimitry Andric const llvm::DataLayout &getDataLayout() const { 7720b57cec5SDimitry Andric return TheModule.getDataLayout(); 7730b57cec5SDimitry Andric } 7740b57cec5SDimitry Andric const TargetInfo &getTarget() const { return Target; } 7750b57cec5SDimitry Andric const llvm::Triple &getTriple() const { return Target.getTriple(); } 7760b57cec5SDimitry Andric bool supportsCOMDAT() const; 7770b57cec5SDimitry Andric void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO); 7780b57cec5SDimitry Andric 779*5deeebd8SDimitry Andric const ABIInfo &getABIInfo(); 7800b57cec5SDimitry Andric CGCXXABI &getCXXABI() const { return *ABI; } 7810b57cec5SDimitry Andric llvm::LLVMContext &getLLVMContext() { return VMContext; } 7820b57cec5SDimitry Andric 7830b57cec5SDimitry Andric bool shouldUseTBAA() const { return TBAA != nullptr; } 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric const TargetCodeGenInfo &getTargetCodeGenInfo(); 7860b57cec5SDimitry Andric 787*5deeebd8SDimitry Andric CodeGenTypes &getTypes() { return *Types; } 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andric CodeGenVTables &getVTables() { return VTables; } 7900b57cec5SDimitry Andric 7910b57cec5SDimitry Andric ItaniumVTableContext &getItaniumVTableContext() { 7920b57cec5SDimitry Andric return VTables.getItaniumVTableContext(); 7930b57cec5SDimitry Andric } 7940b57cec5SDimitry Andric 795bdd1243dSDimitry Andric const ItaniumVTableContext &getItaniumVTableContext() const { 796bdd1243dSDimitry Andric return VTables.getItaniumVTableContext(); 797bdd1243dSDimitry Andric } 798bdd1243dSDimitry Andric 7990b57cec5SDimitry Andric MicrosoftVTableContext &getMicrosoftVTableContext() { 8000b57cec5SDimitry Andric return VTables.getMicrosoftVTableContext(); 8010b57cec5SDimitry Andric } 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric CtorList &getGlobalCtors() { return GlobalCtors; } 8040b57cec5SDimitry Andric CtorList &getGlobalDtors() { return GlobalDtors; } 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric /// getTBAATypeInfo - Get metadata used to describe accesses to objects of 8070b57cec5SDimitry Andric /// the given type. 8080b57cec5SDimitry Andric llvm::MDNode *getTBAATypeInfo(QualType QTy); 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric /// getTBAAAccessInfo - Get TBAA information that describes an access to 8110b57cec5SDimitry Andric /// an object of the given type. 8120b57cec5SDimitry Andric TBAAAccessInfo getTBAAAccessInfo(QualType AccessType); 8130b57cec5SDimitry Andric 8140b57cec5SDimitry Andric /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an 8150b57cec5SDimitry Andric /// access to a virtual table pointer. 8160b57cec5SDimitry Andric TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType); 8170b57cec5SDimitry Andric 8180b57cec5SDimitry Andric llvm::MDNode *getTBAAStructInfo(QualType QTy); 8190b57cec5SDimitry Andric 8200b57cec5SDimitry Andric /// getTBAABaseTypeInfo - Get metadata that describes the given base access 8210b57cec5SDimitry Andric /// type. Return null if the type is not suitable for use in TBAA access tags. 8220b57cec5SDimitry Andric llvm::MDNode *getTBAABaseTypeInfo(QualType QTy); 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric /// getTBAAAccessTagInfo - Get TBAA tag for a given memory access. 8250b57cec5SDimitry Andric llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info); 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of 8280b57cec5SDimitry Andric /// type casts. 8290b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, 8300b57cec5SDimitry Andric TBAAAccessInfo TargetInfo); 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the 8330b57cec5SDimitry Andric /// purposes of conditional operator. 8340b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, 8350b57cec5SDimitry Andric TBAAAccessInfo InfoB); 8360b57cec5SDimitry Andric 8370b57cec5SDimitry Andric /// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the 8380b57cec5SDimitry Andric /// purposes of memory transfer calls. 8390b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, 8400b57cec5SDimitry Andric TBAAAccessInfo SrcInfo); 8410b57cec5SDimitry Andric 8420b57cec5SDimitry Andric /// getTBAAInfoForSubobject - Get TBAA information for an access with a given 8430b57cec5SDimitry Andric /// base lvalue. 8440b57cec5SDimitry Andric TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType) { 8450b57cec5SDimitry Andric if (Base.getTBAAInfo().isMayAlias()) 8460b57cec5SDimitry Andric return TBAAAccessInfo::getMayAliasInfo(); 8470b57cec5SDimitry Andric return getTBAAAccessInfo(AccessType); 8480b57cec5SDimitry Andric } 8490b57cec5SDimitry Andric 8500b57cec5SDimitry Andric bool isPaddedAtomicType(QualType type); 8510b57cec5SDimitry Andric bool isPaddedAtomicType(const AtomicType *type); 8520b57cec5SDimitry Andric 8530b57cec5SDimitry Andric /// DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag. 8540b57cec5SDimitry Andric void DecorateInstructionWithTBAA(llvm::Instruction *Inst, 8550b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo); 8560b57cec5SDimitry Andric 8570b57cec5SDimitry Andric /// Adds !invariant.barrier !tag to instruction 8580b57cec5SDimitry Andric void DecorateInstructionWithInvariantGroup(llvm::Instruction *I, 8590b57cec5SDimitry Andric const CXXRecordDecl *RD); 8600b57cec5SDimitry Andric 8610b57cec5SDimitry Andric /// Emit the given number of characters as a value of type size_t. 8620b57cec5SDimitry Andric llvm::ConstantInt *getSize(CharUnits numChars); 8630b57cec5SDimitry Andric 8640b57cec5SDimitry Andric /// Set the visibility for the given LLVM GlobalValue. 8650b57cec5SDimitry Andric void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const; 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric void setDSOLocal(llvm::GlobalValue *GV) const; 8680b57cec5SDimitry Andric 86981ad6265SDimitry Andric bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const { 87081ad6265SDimitry Andric return getLangOpts().hasDefaultVisibilityExportMapping() && D && 87181ad6265SDimitry Andric (D->getLinkageAndVisibility().getVisibility() == 87281ad6265SDimitry Andric DefaultVisibility) && 87381ad6265SDimitry Andric (getLangOpts().isAllDefaultVisibilityExportMapping() || 87481ad6265SDimitry Andric (getLangOpts().isExplicitDefaultVisibilityExportMapping() && 87581ad6265SDimitry Andric D->getLinkageAndVisibility().isVisibilityExplicit())); 87681ad6265SDimitry Andric } 8770b57cec5SDimitry Andric void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const; 8780b57cec5SDimitry Andric void setDLLImportDLLExport(llvm::GlobalValue *GV, const NamedDecl *D) const; 8790b57cec5SDimitry Andric /// Set visibility, dllimport/dllexport and dso_local. 8800b57cec5SDimitry Andric /// This must be called after dllimport/dllexport is set. 8810b57cec5SDimitry Andric void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const; 8820b57cec5SDimitry Andric void setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D) const; 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric void setGVPropertiesAux(llvm::GlobalValue *GV, const NamedDecl *D) const; 8850b57cec5SDimitry Andric 8860b57cec5SDimitry Andric /// Set the TLS mode for the given LLVM GlobalValue for the thread-local 8870b57cec5SDimitry Andric /// variable declaration D. 8880b57cec5SDimitry Andric void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const; 8890b57cec5SDimitry Andric 8905ffd83dbSDimitry Andric /// Get LLVM TLS mode from CodeGenOptions. 8915ffd83dbSDimitry Andric llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const; 8925ffd83dbSDimitry Andric 8930b57cec5SDimitry Andric static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) { 8940b57cec5SDimitry Andric switch (V) { 8950b57cec5SDimitry Andric case DefaultVisibility: return llvm::GlobalValue::DefaultVisibility; 8960b57cec5SDimitry Andric case HiddenVisibility: return llvm::GlobalValue::HiddenVisibility; 8970b57cec5SDimitry Andric case ProtectedVisibility: return llvm::GlobalValue::ProtectedVisibility; 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric llvm_unreachable("unknown visibility!"); 9000b57cec5SDimitry Andric } 9010b57cec5SDimitry Andric 9020b57cec5SDimitry Andric llvm::Constant *GetAddrOfGlobal(GlobalDecl GD, 9030b57cec5SDimitry Andric ForDefinition_t IsForDefinition 9040b57cec5SDimitry Andric = NotForDefinition); 9050b57cec5SDimitry Andric 9060b57cec5SDimitry Andric /// Will return a global variable of the given type. If a variable with a 9070b57cec5SDimitry Andric /// different type already exists then a new variable with the right type 9080b57cec5SDimitry Andric /// will be created and all uses of the old variable will be replaced with a 9090b57cec5SDimitry Andric /// bitcast to the new variable. 9100b57cec5SDimitry Andric llvm::GlobalVariable * 9110b57cec5SDimitry Andric CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, 9120b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage, 913bdd1243dSDimitry Andric llvm::Align Alignment); 9140b57cec5SDimitry Andric 9155ffd83dbSDimitry Andric llvm::Function *CreateGlobalInitOrCleanUpFunction( 9165ffd83dbSDimitry Andric llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, 91781ad6265SDimitry Andric SourceLocation Loc = SourceLocation(), bool TLS = false, 91881ad6265SDimitry Andric llvm::GlobalVariable::LinkageTypes Linkage = 91981ad6265SDimitry Andric llvm::GlobalVariable::InternalLinkage); 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric /// Return the AST address space of the underlying global variable for D, as 9220b57cec5SDimitry Andric /// determined by its declaration. Normally this is the same as the address 9230b57cec5SDimitry Andric /// space of D's type, but in CUDA, address spaces are associated with 9240b57cec5SDimitry Andric /// declarations, not types. If D is nullptr, return the default address 9250b57cec5SDimitry Andric /// space for global variable. 9260b57cec5SDimitry Andric /// 9270b57cec5SDimitry Andric /// For languages without explicit address spaces, if D has default address 9280b57cec5SDimitry Andric /// space, target-specific global or constant address space may be returned. 9290b57cec5SDimitry Andric LangAS GetGlobalVarAddressSpace(const VarDecl *D); 9300b57cec5SDimitry Andric 931fe6060f1SDimitry Andric /// Return the AST address space of constant literal, which is used to emit 932fe6060f1SDimitry Andric /// the constant literal as global variable in LLVM IR. 933fe6060f1SDimitry Andric /// Note: This is not necessarily the address space of the constant literal 934fe6060f1SDimitry Andric /// in AST. For address space agnostic language, e.g. C++, constant literal 935fe6060f1SDimitry Andric /// in AST is always in default address space. 936fe6060f1SDimitry Andric LangAS GetGlobalConstantAddressSpace() const; 937fe6060f1SDimitry Andric 9380b57cec5SDimitry Andric /// Return the llvm::Constant for the address of the given global variable. 9390b57cec5SDimitry Andric /// If Ty is non-null and if the global doesn't exist, then it will be created 9400b57cec5SDimitry Andric /// with the specified type instead of whatever the normal requested type 9410b57cec5SDimitry Andric /// would be. If IsForDefinition is true, it is guaranteed that an actual 9420b57cec5SDimitry Andric /// global with type Ty will be returned, not conversion of a variable with 9430b57cec5SDimitry Andric /// the same mangled name but some other type. 9440b57cec5SDimitry Andric llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D, 9450b57cec5SDimitry Andric llvm::Type *Ty = nullptr, 9460b57cec5SDimitry Andric ForDefinition_t IsForDefinition 9470b57cec5SDimitry Andric = NotForDefinition); 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric /// Return the address of the given function. If Ty is non-null, then this 9500b57cec5SDimitry Andric /// function will use the specified type if it has to create it. 9510b57cec5SDimitry Andric llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = nullptr, 9520b57cec5SDimitry Andric bool ForVTable = false, 9530b57cec5SDimitry Andric bool DontDefer = false, 9540b57cec5SDimitry Andric ForDefinition_t IsForDefinition 9550b57cec5SDimitry Andric = NotForDefinition); 9560b57cec5SDimitry Andric 9570eae32dcSDimitry Andric // Return the function body address of the given function. 9580eae32dcSDimitry Andric llvm::Constant *GetFunctionStart(const ValueDecl *Decl); 9590eae32dcSDimitry Andric 9600fca6ea1SDimitry Andric /// Return a function pointer for a reference to the given function. 9610fca6ea1SDimitry Andric /// This correctly handles weak references, but does not apply a 9620fca6ea1SDimitry Andric /// pointer signature. 9630fca6ea1SDimitry Andric llvm::Constant *getRawFunctionPointer(GlobalDecl GD, 9640fca6ea1SDimitry Andric llvm::Type *Ty = nullptr); 9650fca6ea1SDimitry Andric 9660fca6ea1SDimitry Andric /// Return the ABI-correct function pointer value for a reference 9670fca6ea1SDimitry Andric /// to the given function. This will apply a pointer signature if 9680fca6ea1SDimitry Andric /// necessary, caching the result for the given function. 9690fca6ea1SDimitry Andric llvm::Constant *getFunctionPointer(GlobalDecl GD, llvm::Type *Ty = nullptr); 9700fca6ea1SDimitry Andric 9710fca6ea1SDimitry Andric /// Return the ABI-correct function pointer value for a reference 9720fca6ea1SDimitry Andric /// to the given function. This will apply a pointer signature if 9730fca6ea1SDimitry Andric /// necessary. 9740fca6ea1SDimitry Andric llvm::Constant *getFunctionPointer(llvm::Constant *Pointer, 9750fca6ea1SDimitry Andric QualType FunctionType); 9760fca6ea1SDimitry Andric 9770fca6ea1SDimitry Andric llvm::Constant *getMemberFunctionPointer(const FunctionDecl *FD, 9780fca6ea1SDimitry Andric llvm::Type *Ty = nullptr); 9790fca6ea1SDimitry Andric 9800fca6ea1SDimitry Andric llvm::Constant *getMemberFunctionPointer(llvm::Constant *Pointer, 9810fca6ea1SDimitry Andric QualType FT); 9820fca6ea1SDimitry Andric 9830fca6ea1SDimitry Andric CGPointerAuthInfo getFunctionPointerAuthInfo(QualType T); 9840fca6ea1SDimitry Andric 9850fca6ea1SDimitry Andric CGPointerAuthInfo getMemberFunctionPointerAuthInfo(QualType FT); 9860fca6ea1SDimitry Andric 9870fca6ea1SDimitry Andric CGPointerAuthInfo getPointerAuthInfoForPointeeType(QualType type); 9880fca6ea1SDimitry Andric 9890fca6ea1SDimitry Andric CGPointerAuthInfo getPointerAuthInfoForType(QualType type); 9900fca6ea1SDimitry Andric 9910fca6ea1SDimitry Andric bool shouldSignPointer(const PointerAuthSchema &Schema); 9920fca6ea1SDimitry Andric llvm::Constant *getConstantSignedPointer(llvm::Constant *Pointer, 9930fca6ea1SDimitry Andric const PointerAuthSchema &Schema, 9940fca6ea1SDimitry Andric llvm::Constant *StorageAddress, 9950fca6ea1SDimitry Andric GlobalDecl SchemaDecl, 9960fca6ea1SDimitry Andric QualType SchemaType); 9970fca6ea1SDimitry Andric 9980fca6ea1SDimitry Andric llvm::Constant * 9990fca6ea1SDimitry Andric getConstantSignedPointer(llvm::Constant *Pointer, unsigned Key, 10000fca6ea1SDimitry Andric llvm::Constant *StorageAddress, 10010fca6ea1SDimitry Andric llvm::ConstantInt *OtherDiscriminator); 10020fca6ea1SDimitry Andric 10030fca6ea1SDimitry Andric llvm::ConstantInt * 10040fca6ea1SDimitry Andric getPointerAuthOtherDiscriminator(const PointerAuthSchema &Schema, 10050fca6ea1SDimitry Andric GlobalDecl SchemaDecl, QualType SchemaType); 10060fca6ea1SDimitry Andric 10070fca6ea1SDimitry Andric uint16_t getPointerAuthDeclDiscriminator(GlobalDecl GD); 10080fca6ea1SDimitry Andric std::optional<CGPointerAuthInfo> 10090fca6ea1SDimitry Andric getVTablePointerAuthInfo(CodeGenFunction *Context, 10100fca6ea1SDimitry Andric const CXXRecordDecl *Record, 10110fca6ea1SDimitry Andric llvm::Value *StorageAddress); 10120fca6ea1SDimitry Andric 10130fca6ea1SDimitry Andric std::optional<PointerAuthQualifier> 10140fca6ea1SDimitry Andric getVTablePointerAuthentication(const CXXRecordDecl *thisClass); 10150fca6ea1SDimitry Andric 10160fca6ea1SDimitry Andric CGPointerAuthInfo EmitPointerAuthInfo(const RecordDecl *RD); 10170fca6ea1SDimitry Andric 101806c3fb27SDimitry Andric // Return whether RTTI information should be emitted for this target. 101906c3fb27SDimitry Andric bool shouldEmitRTTI(bool ForEH = false) { 102006c3fb27SDimitry Andric return (ForEH || getLangOpts().RTTI) && !getLangOpts().CUDAIsDevice && 102106c3fb27SDimitry Andric !(getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice && 10220fca6ea1SDimitry Andric (getTriple().isNVPTX() || getTriple().isAMDGPU())); 102306c3fb27SDimitry Andric } 102406c3fb27SDimitry Andric 10250b57cec5SDimitry Andric /// Get the address of the RTTI descriptor for the given type. 10260b57cec5SDimitry Andric llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false); 10270b57cec5SDimitry Andric 10285ffd83dbSDimitry Andric /// Get the address of a GUID. 10295ffd83dbSDimitry Andric ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD); 10300b57cec5SDimitry Andric 103181ad6265SDimitry Andric /// Get the address of a UnnamedGlobalConstant 103281ad6265SDimitry Andric ConstantAddress 103381ad6265SDimitry Andric GetAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *GCD); 103481ad6265SDimitry Andric 1035e8d8bef9SDimitry Andric /// Get the address of a template parameter object. 1036e8d8bef9SDimitry Andric ConstantAddress 1037e8d8bef9SDimitry Andric GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO); 1038e8d8bef9SDimitry Andric 10390b57cec5SDimitry Andric /// Get the address of the thunk for the given global decl. 10400b57cec5SDimitry Andric llvm::Constant *GetAddrOfThunk(StringRef Name, llvm::Type *FnTy, 10410b57cec5SDimitry Andric GlobalDecl GD); 10420b57cec5SDimitry Andric 10430b57cec5SDimitry Andric /// Get a reference to the target of VD. 10440b57cec5SDimitry Andric ConstantAddress GetWeakRefReference(const ValueDecl *VD); 10450b57cec5SDimitry Andric 10460b57cec5SDimitry Andric /// Returns the assumed alignment of an opaque pointer to the given class. 10470b57cec5SDimitry Andric CharUnits getClassPointerAlignment(const CXXRecordDecl *CD); 10480b57cec5SDimitry Andric 10495ffd83dbSDimitry Andric /// Returns the minimum object size for an object of the given class type 10505ffd83dbSDimitry Andric /// (or a class derived from it). 10515ffd83dbSDimitry Andric CharUnits getMinimumClassObjectSize(const CXXRecordDecl *CD); 10525ffd83dbSDimitry Andric 10535ffd83dbSDimitry Andric /// Returns the minimum object size for an object of the given type. 10545ffd83dbSDimitry Andric CharUnits getMinimumObjectSize(QualType Ty) { 10555ffd83dbSDimitry Andric if (CXXRecordDecl *RD = Ty->getAsCXXRecordDecl()) 10565ffd83dbSDimitry Andric return getMinimumClassObjectSize(RD); 10575ffd83dbSDimitry Andric return getContext().getTypeSizeInChars(Ty); 10585ffd83dbSDimitry Andric } 10595ffd83dbSDimitry Andric 10600b57cec5SDimitry Andric /// Returns the assumed alignment of a virtual base of a class. 10610b57cec5SDimitry Andric CharUnits getVBaseAlignment(CharUnits DerivedAlign, 10620b57cec5SDimitry Andric const CXXRecordDecl *Derived, 10630b57cec5SDimitry Andric const CXXRecordDecl *VBase); 10640b57cec5SDimitry Andric 10650b57cec5SDimitry Andric /// Given a class pointer with an actual known alignment, and the 10660b57cec5SDimitry Andric /// expected alignment of an object at a dynamic offset w.r.t that 10670b57cec5SDimitry Andric /// pointer, return the alignment to assume at the offset. 10680b57cec5SDimitry Andric CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, 10690b57cec5SDimitry Andric const CXXRecordDecl *Class, 10700b57cec5SDimitry Andric CharUnits ExpectedTargetAlign); 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andric CharUnits 10730b57cec5SDimitry Andric computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, 10740b57cec5SDimitry Andric CastExpr::path_const_iterator Start, 10750b57cec5SDimitry Andric CastExpr::path_const_iterator End); 10760b57cec5SDimitry Andric 10770b57cec5SDimitry Andric /// Returns the offset from a derived class to a class. Returns null if the 10780b57cec5SDimitry Andric /// offset is 0. 10790b57cec5SDimitry Andric llvm::Constant * 10800b57cec5SDimitry Andric GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 10810b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 10820b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd); 10830b57cec5SDimitry Andric 10840b57cec5SDimitry Andric llvm::FoldingSet<BlockByrefHelpers> ByrefHelpersCache; 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andric /// Fetches the global unique block count. 10870b57cec5SDimitry Andric int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; } 10880b57cec5SDimitry Andric 10890b57cec5SDimitry Andric /// Fetches the type of a generic block descriptor. 10900b57cec5SDimitry Andric llvm::Type *getBlockDescriptorType(); 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andric /// The type of a generic block literal. 10930b57cec5SDimitry Andric llvm::Type *getGenericBlockLiteralType(); 10940b57cec5SDimitry Andric 10950b57cec5SDimitry Andric /// Gets the address of a block which requires no captures. 10960b57cec5SDimitry Andric llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name); 10970b57cec5SDimitry Andric 10980b57cec5SDimitry Andric /// Returns the address of a block which requires no caputres, or null if 10990b57cec5SDimitry Andric /// we've yet to emit the block for BE. 11000b57cec5SDimitry Andric llvm::Constant *getAddrOfGlobalBlockIfEmitted(const BlockExpr *BE) { 11010b57cec5SDimitry Andric return EmittedGlobalBlocks.lookup(BE); 11020b57cec5SDimitry Andric } 11030b57cec5SDimitry Andric 11040b57cec5SDimitry Andric /// Notes that BE's global block is available via Addr. Asserts that BE 11050b57cec5SDimitry Andric /// isn't already emitted. 11060b57cec5SDimitry Andric void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr); 11070b57cec5SDimitry Andric 11080b57cec5SDimitry Andric /// Return a pointer to a constant CFString object for the given string. 11090b57cec5SDimitry Andric ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal); 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric /// Return a constant array for the given string. 11120b57cec5SDimitry Andric llvm::Constant *GetConstantArrayFromStringLiteral(const StringLiteral *E); 11130b57cec5SDimitry Andric 11140b57cec5SDimitry Andric /// Return a pointer to a constant array for the given string literal. 11150b57cec5SDimitry Andric ConstantAddress 11160b57cec5SDimitry Andric GetAddrOfConstantStringFromLiteral(const StringLiteral *S, 11170b57cec5SDimitry Andric StringRef Name = ".str"); 11180b57cec5SDimitry Andric 11190b57cec5SDimitry Andric /// Return a pointer to a constant array for the given ObjCEncodeExpr node. 11200b57cec5SDimitry Andric ConstantAddress 11210b57cec5SDimitry Andric GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *); 11220b57cec5SDimitry Andric 11230b57cec5SDimitry Andric /// Returns a pointer to a character array containing the literal and a 11240b57cec5SDimitry Andric /// terminating '\0' character. The result has pointer to array type. 11250b57cec5SDimitry Andric /// 11260b57cec5SDimitry Andric /// \param GlobalName If provided, the name to use for the global (if one is 11270b57cec5SDimitry Andric /// created). 11280b57cec5SDimitry Andric ConstantAddress 11290b57cec5SDimitry Andric GetAddrOfConstantCString(const std::string &Str, 11300b57cec5SDimitry Andric const char *GlobalName = nullptr); 11310b57cec5SDimitry Andric 11320b57cec5SDimitry Andric /// Returns a pointer to a constant global variable for the given file-scope 11330b57cec5SDimitry Andric /// compound literal expression. 11340b57cec5SDimitry Andric ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E); 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric /// If it's been emitted already, returns the GlobalVariable corresponding to 11370b57cec5SDimitry Andric /// a compound literal. Otherwise, returns null. 11380b57cec5SDimitry Andric llvm::GlobalVariable * 11390b57cec5SDimitry Andric getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E); 11400b57cec5SDimitry Andric 11410b57cec5SDimitry Andric /// Notes that CLE's GlobalVariable is GV. Asserts that CLE isn't already 11420b57cec5SDimitry Andric /// emitted. 11430b57cec5SDimitry Andric void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE, 11440b57cec5SDimitry Andric llvm::GlobalVariable *GV); 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric /// Returns a pointer to a global variable representing a temporary 11470b57cec5SDimitry Andric /// with static or thread storage duration. 11480b57cec5SDimitry Andric ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, 11490b57cec5SDimitry Andric const Expr *Inner); 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric /// Retrieve the record type that describes the state of an 11520b57cec5SDimitry Andric /// Objective-C fast enumeration loop (for..in). 11530b57cec5SDimitry Andric QualType getObjCFastEnumerationStateType(); 11540b57cec5SDimitry Andric 11550b57cec5SDimitry Andric // Produce code for this constructor/destructor. This method doesn't try 11560b57cec5SDimitry Andric // to apply any ABI rules about which other constructors/destructors 11570b57cec5SDimitry Andric // are needed or if they are alias to each other. 11580b57cec5SDimitry Andric llvm::Function *codegenCXXStructor(GlobalDecl GD); 11590b57cec5SDimitry Andric 11600b57cec5SDimitry Andric /// Return the address of the constructor/destructor of the given type. 11610b57cec5SDimitry Andric llvm::Constant * 11620b57cec5SDimitry Andric getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr, 11630b57cec5SDimitry Andric llvm::FunctionType *FnType = nullptr, 11640b57cec5SDimitry Andric bool DontDefer = false, 11650b57cec5SDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition) { 11660b57cec5SDimitry Andric return cast<llvm::Constant>(getAddrAndTypeOfCXXStructor(GD, FnInfo, FnType, 11670b57cec5SDimitry Andric DontDefer, 11680b57cec5SDimitry Andric IsForDefinition) 11690b57cec5SDimitry Andric .getCallee()); 11700b57cec5SDimitry Andric } 11710b57cec5SDimitry Andric 11720b57cec5SDimitry Andric llvm::FunctionCallee getAddrAndTypeOfCXXStructor( 11730b57cec5SDimitry Andric GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr, 11740b57cec5SDimitry Andric llvm::FunctionType *FnType = nullptr, bool DontDefer = false, 11750b57cec5SDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition); 11760b57cec5SDimitry Andric 11770b57cec5SDimitry Andric /// Given a builtin id for a function like "__builtin_fabsf", return a 11780b57cec5SDimitry Andric /// Function* for "fabsf". 11790b57cec5SDimitry Andric llvm::Constant *getBuiltinLibFunction(const FunctionDecl *FD, 11800b57cec5SDimitry Andric unsigned BuiltinID); 11810b57cec5SDimitry Andric 1182bdd1243dSDimitry Andric llvm::Function *getIntrinsic(unsigned IID, 1183bdd1243dSDimitry Andric ArrayRef<llvm::Type *> Tys = std::nullopt); 11840b57cec5SDimitry Andric 11850b57cec5SDimitry Andric /// Emit code for a single top level declaration. 11860b57cec5SDimitry Andric void EmitTopLevelDecl(Decl *D); 11870b57cec5SDimitry Andric 11880b57cec5SDimitry Andric /// Stored a deferred empty coverage mapping for an unused 11890b57cec5SDimitry Andric /// and thus uninstrumented top level declaration. 11900b57cec5SDimitry Andric void AddDeferredUnusedCoverageMapping(Decl *D); 11910b57cec5SDimitry Andric 11920b57cec5SDimitry Andric /// Remove the deferred empty coverage mapping as this 11930b57cec5SDimitry Andric /// declaration is actually instrumented. 11940b57cec5SDimitry Andric void ClearUnusedCoverageMapping(const Decl *D); 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric /// Emit all the deferred coverage mappings 11970b57cec5SDimitry Andric /// for the uninstrumented functions. 11980b57cec5SDimitry Andric void EmitDeferredUnusedCoverageMappings(); 11990b57cec5SDimitry Andric 12005ffd83dbSDimitry Andric /// Emit an alias for "main" if it has no arguments (needed for wasm). 12015ffd83dbSDimitry Andric void EmitMainVoidAlias(); 12025ffd83dbSDimitry Andric 12030b57cec5SDimitry Andric /// Tell the consumer that this variable has been instantiated. 12040b57cec5SDimitry Andric void HandleCXXStaticMemberVarInstantiation(VarDecl *VD); 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric /// If the declaration has internal linkage but is inside an 12070b57cec5SDimitry Andric /// extern "C" linkage specification, prepare to emit an alias for it 12080b57cec5SDimitry Andric /// to the expected name. 12090b57cec5SDimitry Andric template<typename SomeDecl> 12100b57cec5SDimitry Andric void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV); 12110b57cec5SDimitry Andric 12120b57cec5SDimitry Andric /// Add a global to a list to be added to the llvm.used metadata. 12130b57cec5SDimitry Andric void addUsedGlobal(llvm::GlobalValue *GV); 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andric /// Add a global to a list to be added to the llvm.compiler.used metadata. 12160b57cec5SDimitry Andric void addCompilerUsedGlobal(llvm::GlobalValue *GV); 12170b57cec5SDimitry Andric 1218fe6060f1SDimitry Andric /// Add a global to a list to be added to the llvm.compiler.used metadata. 1219fe6060f1SDimitry Andric void addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV); 1220fe6060f1SDimitry Andric 12210b57cec5SDimitry Andric /// Add a destructor and object to add to the C++ global destructor function. 12220b57cec5SDimitry Andric void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object) { 12235ffd83dbSDimitry Andric CXXGlobalDtorsOrStermFinalizers.emplace_back(DtorFn.getFunctionType(), 12245ffd83dbSDimitry Andric DtorFn.getCallee(), Object); 12255ffd83dbSDimitry Andric } 12265ffd83dbSDimitry Andric 12275ffd83dbSDimitry Andric /// Add an sterm finalizer to the C++ global cleanup function. 12285ffd83dbSDimitry Andric void AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn) { 12295ffd83dbSDimitry Andric CXXGlobalDtorsOrStermFinalizers.emplace_back(DtorFn.getFunctionType(), 12305ffd83dbSDimitry Andric DtorFn.getCallee(), nullptr); 12310b57cec5SDimitry Andric } 12320b57cec5SDimitry Andric 1233e8d8bef9SDimitry Andric /// Add an sterm finalizer to its own llvm.global_dtors entry. 1234e8d8bef9SDimitry Andric void AddCXXStermFinalizerToGlobalDtor(llvm::Function *StermFinalizer, 1235e8d8bef9SDimitry Andric int Priority) { 1236e8d8bef9SDimitry Andric AddGlobalDtor(StermFinalizer, Priority); 1237e8d8bef9SDimitry Andric } 1238e8d8bef9SDimitry Andric 1239fe6060f1SDimitry Andric void AddCXXPrioritizedStermFinalizerEntry(llvm::Function *StermFinalizer, 1240fe6060f1SDimitry Andric int Priority) { 1241fe6060f1SDimitry Andric OrderGlobalInitsOrStermFinalizers Key(Priority, 1242fe6060f1SDimitry Andric PrioritizedCXXStermFinalizers.size()); 1243fe6060f1SDimitry Andric PrioritizedCXXStermFinalizers.push_back( 1244fe6060f1SDimitry Andric std::make_pair(Key, StermFinalizer)); 1245fe6060f1SDimitry Andric } 1246fe6060f1SDimitry Andric 12470b57cec5SDimitry Andric /// Create or return a runtime function declaration with the specified type 1248480093f4SDimitry Andric /// and name. If \p AssumeConvergent is true, the call will have the 1249480093f4SDimitry Andric /// convergent attribute added. 12500b57cec5SDimitry Andric llvm::FunctionCallee 12510b57cec5SDimitry Andric CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, 12520b57cec5SDimitry Andric llvm::AttributeList ExtraAttrs = llvm::AttributeList(), 1253480093f4SDimitry Andric bool Local = false, bool AssumeConvergent = false); 1254480093f4SDimitry Andric 12550b57cec5SDimitry Andric /// Create a new runtime global variable with the specified type and name. 12560b57cec5SDimitry Andric llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty, 12570b57cec5SDimitry Andric StringRef Name); 12580b57cec5SDimitry Andric 12590b57cec5SDimitry Andric ///@name Custom Blocks Runtime Interfaces 12600b57cec5SDimitry Andric ///@{ 12610b57cec5SDimitry Andric 12620b57cec5SDimitry Andric llvm::Constant *getNSConcreteGlobalBlock(); 12630b57cec5SDimitry Andric llvm::Constant *getNSConcreteStackBlock(); 12640b57cec5SDimitry Andric llvm::FunctionCallee getBlockObjectAssign(); 12650b57cec5SDimitry Andric llvm::FunctionCallee getBlockObjectDispose(); 12660b57cec5SDimitry Andric 12670b57cec5SDimitry Andric ///@} 12680b57cec5SDimitry Andric 12690b57cec5SDimitry Andric llvm::Function *getLLVMLifetimeStartFn(); 12700b57cec5SDimitry Andric llvm::Function *getLLVMLifetimeEndFn(); 12710b57cec5SDimitry Andric 12720b57cec5SDimitry Andric // Make sure that this type is translated. 12730b57cec5SDimitry Andric void UpdateCompletedType(const TagDecl *TD); 12740b57cec5SDimitry Andric 12750b57cec5SDimitry Andric llvm::Constant *getMemberPointerConstant(const UnaryOperator *e); 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andric /// Emit type info if type of an expression is a variably modified 12780b57cec5SDimitry Andric /// type. Also emit proper debug info for cast types. 12790b57cec5SDimitry Andric void EmitExplicitCastExprType(const ExplicitCastExpr *E, 12800b57cec5SDimitry Andric CodeGenFunction *CGF = nullptr); 12810b57cec5SDimitry Andric 12820b57cec5SDimitry Andric /// Return the result of value-initializing the given type, i.e. a null 12830b57cec5SDimitry Andric /// expression of the given type. This is usually, but not always, an LLVM 12840b57cec5SDimitry Andric /// null constant. 12850b57cec5SDimitry Andric llvm::Constant *EmitNullConstant(QualType T); 12860b57cec5SDimitry Andric 12870b57cec5SDimitry Andric /// Return a null constant appropriate for zero-initializing a base class with 12880b57cec5SDimitry Andric /// the given type. This is usually, but not always, an LLVM null constant. 12890b57cec5SDimitry Andric llvm::Constant *EmitNullConstantForBase(const CXXRecordDecl *Record); 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric /// Emit a general error that something can't be done. 12920b57cec5SDimitry Andric void Error(SourceLocation loc, StringRef error); 12930b57cec5SDimitry Andric 12940b57cec5SDimitry Andric /// Print out an error that codegen doesn't support the specified stmt yet. 12950b57cec5SDimitry Andric void ErrorUnsupported(const Stmt *S, const char *Type); 12960b57cec5SDimitry Andric 12970b57cec5SDimitry Andric /// Print out an error that codegen doesn't support the specified decl yet. 12980b57cec5SDimitry Andric void ErrorUnsupported(const Decl *D, const char *Type); 12990b57cec5SDimitry Andric 13000b57cec5SDimitry Andric /// Set the attributes on the LLVM function for the given decl and function 13010b57cec5SDimitry Andric /// info. This applies attributes necessary for handling the ABI as well as 13020b57cec5SDimitry Andric /// user specified attributes like section. 13030b57cec5SDimitry Andric void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, 13040b57cec5SDimitry Andric const CGFunctionInfo &FI); 13050b57cec5SDimitry Andric 13060b57cec5SDimitry Andric /// Set the LLVM function attributes (sext, zext, etc). 13070b57cec5SDimitry Andric void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, 1308fe6060f1SDimitry Andric llvm::Function *F, bool IsThunk); 13090b57cec5SDimitry Andric 13100b57cec5SDimitry Andric /// Set the LLVM function attributes which only apply to a function 13110b57cec5SDimitry Andric /// definition. 13120b57cec5SDimitry Andric void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F); 13130b57cec5SDimitry Andric 1314e8d8bef9SDimitry Andric /// Set the LLVM function attributes that represent floating point 1315e8d8bef9SDimitry Andric /// environment. 1316e8d8bef9SDimitry Andric void setLLVMFunctionFEnvAttributes(const FunctionDecl *D, llvm::Function *F); 1317e8d8bef9SDimitry Andric 13180b57cec5SDimitry Andric /// Return true iff the given type uses 'sret' when used as a return type. 13190b57cec5SDimitry Andric bool ReturnTypeUsesSRet(const CGFunctionInfo &FI); 13200b57cec5SDimitry Andric 13215678d1d9SDimitry Andric /// Return true iff the given type has `inreg` set. 13225678d1d9SDimitry Andric bool ReturnTypeHasInReg(const CGFunctionInfo &FI); 13235678d1d9SDimitry Andric 13240b57cec5SDimitry Andric /// Return true iff the given type uses an argument slot when 'sret' is used 13250b57cec5SDimitry Andric /// as a return type. 13260b57cec5SDimitry Andric bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI); 13270b57cec5SDimitry Andric 13280b57cec5SDimitry Andric /// Return true iff the given type uses 'fpret' when used as a return type. 13290b57cec5SDimitry Andric bool ReturnTypeUsesFPRet(QualType ResultType); 13300b57cec5SDimitry Andric 13310b57cec5SDimitry Andric /// Return true iff the given type uses 'fp2ret' when used as a return type. 13320b57cec5SDimitry Andric bool ReturnTypeUsesFP2Ret(QualType ResultType); 13330b57cec5SDimitry Andric 13340b57cec5SDimitry Andric /// Get the LLVM attributes and calling convention to use for a particular 13350b57cec5SDimitry Andric /// function type. 13360b57cec5SDimitry Andric /// 13370b57cec5SDimitry Andric /// \param Name - The function name. 13380b57cec5SDimitry Andric /// \param Info - The function type information. 13390b57cec5SDimitry Andric /// \param CalleeInfo - The callee information these attributes are being 13400b57cec5SDimitry Andric /// constructed for. If valid, the attributes applied to this decl may 13410b57cec5SDimitry Andric /// contribute to the function attributes and calling convention. 13420b57cec5SDimitry Andric /// \param Attrs [out] - On return, the attribute list to use. 13430b57cec5SDimitry Andric /// \param CallingConv [out] - On return, the LLVM calling convention to use. 13440b57cec5SDimitry Andric void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, 13450b57cec5SDimitry Andric CGCalleeInfo CalleeInfo, 13460b57cec5SDimitry Andric llvm::AttributeList &Attrs, unsigned &CallingConv, 1347fe6060f1SDimitry Andric bool AttrOnCallSite, bool IsThunk); 13480b57cec5SDimitry Andric 13495f757f3fSDimitry Andric /// Adjust Memory attribute to ensure that the BE gets the right attribute 13505f757f3fSDimitry Andric // in order to generate the library call or the intrinsic for the function 13515f757f3fSDimitry Andric // name 'Name'. 13525f757f3fSDimitry Andric void AdjustMemoryAttribute(StringRef Name, CGCalleeInfo CalleeInfo, 13535f757f3fSDimitry Andric llvm::AttributeList &Attrs); 13545ffd83dbSDimitry Andric 13555ffd83dbSDimitry Andric /// Like the overload taking a `Function &`, but intended specifically 13565ffd83dbSDimitry Andric /// for frontends that want to build on Clang's target-configuration logic. 13575ffd83dbSDimitry Andric void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs); 13580b57cec5SDimitry Andric 13590b57cec5SDimitry Andric StringRef getMangledName(GlobalDecl GD); 13600b57cec5SDimitry Andric StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD); 136181ad6265SDimitry Andric const GlobalDecl getMangledNameDecl(StringRef); 13620b57cec5SDimitry Andric 13630b57cec5SDimitry Andric void EmitTentativeDefinition(const VarDecl *D); 13640b57cec5SDimitry Andric 13650fca6ea1SDimitry Andric void EmitExternalDeclaration(const DeclaratorDecl *D); 1366480093f4SDimitry Andric 13670b57cec5SDimitry Andric void EmitVTable(CXXRecordDecl *Class); 13680b57cec5SDimitry Andric 13690b57cec5SDimitry Andric void RefreshTypeCacheForClass(const CXXRecordDecl *Class); 13700b57cec5SDimitry Andric 13710b57cec5SDimitry Andric /// Appends Opts to the "llvm.linker.options" metadata value. 13720b57cec5SDimitry Andric void AppendLinkerOptions(StringRef Opts); 13730b57cec5SDimitry Andric 13740b57cec5SDimitry Andric /// Appends a detect mismatch command to the linker options. 13750b57cec5SDimitry Andric void AddDetectMismatch(StringRef Name, StringRef Value); 13760b57cec5SDimitry Andric 13770b57cec5SDimitry Andric /// Appends a dependent lib to the appropriate metadata value. 13780b57cec5SDimitry Andric void AddDependentLib(StringRef Lib); 13790b57cec5SDimitry Andric 13800b57cec5SDimitry Andric 13810b57cec5SDimitry Andric llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD); 13820b57cec5SDimitry Andric 13830b57cec5SDimitry Andric void setFunctionLinkage(GlobalDecl GD, llvm::Function *F) { 13840b57cec5SDimitry Andric F->setLinkage(getFunctionLinkage(GD)); 13850b57cec5SDimitry Andric } 13860b57cec5SDimitry Andric 13870b57cec5SDimitry Andric /// Return the appropriate linkage for the vtable, VTT, and type information 13880b57cec5SDimitry Andric /// of the given class. 13890b57cec5SDimitry Andric llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD); 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric /// Return the store size, in character units, of the given LLVM type. 13920b57cec5SDimitry Andric CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const; 13930b57cec5SDimitry Andric 13940b57cec5SDimitry Andric /// Returns LLVM linkage for a declarator. 13950b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes 13968a4dda33SDimitry Andric getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage); 13970b57cec5SDimitry Andric 13980b57cec5SDimitry Andric /// Returns LLVM linkage for a declarator. 13990b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes 14008a4dda33SDimitry Andric getLLVMLinkageVarDefinition(const VarDecl *VD); 14010b57cec5SDimitry Andric 14020b57cec5SDimitry Andric /// Emit all the global annotations. 14030b57cec5SDimitry Andric void EmitGlobalAnnotations(); 14040b57cec5SDimitry Andric 14050b57cec5SDimitry Andric /// Emit an annotation string. 14060b57cec5SDimitry Andric llvm::Constant *EmitAnnotationString(StringRef Str); 14070b57cec5SDimitry Andric 14080b57cec5SDimitry Andric /// Emit the annotation's translation unit. 14090b57cec5SDimitry Andric llvm::Constant *EmitAnnotationUnit(SourceLocation Loc); 14100b57cec5SDimitry Andric 14110b57cec5SDimitry Andric /// Emit the annotation line number. 14120b57cec5SDimitry Andric llvm::Constant *EmitAnnotationLineNo(SourceLocation L); 14130b57cec5SDimitry Andric 1414e8d8bef9SDimitry Andric /// Emit additional args of the annotation. 1415e8d8bef9SDimitry Andric llvm::Constant *EmitAnnotationArgs(const AnnotateAttr *Attr); 1416e8d8bef9SDimitry Andric 14170b57cec5SDimitry Andric /// Generate the llvm::ConstantStruct which contains the annotation 14180b57cec5SDimitry Andric /// information for a given GlobalValue. The annotation struct is 14190b57cec5SDimitry Andric /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the 14200b57cec5SDimitry Andric /// GlobalValue being annotated. The second field is the constant string 14210b57cec5SDimitry Andric /// created from the AnnotateAttr's annotation. The third field is a constant 14220b57cec5SDimitry Andric /// string containing the name of the translation unit. The fourth field is 14230b57cec5SDimitry Andric /// the line number in the file of the annotated value declaration. 14240b57cec5SDimitry Andric llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV, 14250b57cec5SDimitry Andric const AnnotateAttr *AA, 14260b57cec5SDimitry Andric SourceLocation L); 14270b57cec5SDimitry Andric 14280b57cec5SDimitry Andric /// Add global annotations that are set on D, for the global GV. Those 14290b57cec5SDimitry Andric /// annotations are emitted during finalization of the LLVM code. 14300b57cec5SDimitry Andric void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); 14310b57cec5SDimitry Andric 1432fe6060f1SDimitry Andric bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn, 14330b57cec5SDimitry Andric SourceLocation Loc) const; 14340b57cec5SDimitry Andric 143581ad6265SDimitry Andric bool isInNoSanitizeList(SanitizerMask Kind, llvm::GlobalVariable *GV, 143681ad6265SDimitry Andric SourceLocation Loc, QualType Ty, 143781ad6265SDimitry Andric StringRef Category = StringRef()) const; 14380b57cec5SDimitry Andric 14390b57cec5SDimitry Andric /// Imbue XRay attributes to a function, applying the always/never attribute 14400b57cec5SDimitry Andric /// lists in the process. Returns true if we did imbue attributes this way, 14410b57cec5SDimitry Andric /// false otherwise. 14420b57cec5SDimitry Andric bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, 14430b57cec5SDimitry Andric StringRef Category = StringRef()) const; 14440b57cec5SDimitry Andric 1445fcaf7f86SDimitry Andric /// \returns true if \p Fn at \p Loc should be excluded from profile 1446fcaf7f86SDimitry Andric /// instrumentation by the SCL passed by \p -fprofile-list. 1447bdd1243dSDimitry Andric ProfileList::ExclusionType 1448bdd1243dSDimitry Andric isFunctionBlockedByProfileList(llvm::Function *Fn, SourceLocation Loc) const; 1449fcaf7f86SDimitry Andric 1450fcaf7f86SDimitry Andric /// \returns true if \p Fn at \p Loc should be excluded from profile 1451fcaf7f86SDimitry Andric /// instrumentation. 1452bdd1243dSDimitry Andric ProfileList::ExclusionType 1453bdd1243dSDimitry Andric isFunctionBlockedFromProfileInstr(llvm::Function *Fn, 1454fcaf7f86SDimitry Andric SourceLocation Loc) const; 1455e8d8bef9SDimitry Andric 14560b57cec5SDimitry Andric SanitizerMetadata *getSanitizerMetadata() { 14570b57cec5SDimitry Andric return SanitizerMD.get(); 14580b57cec5SDimitry Andric } 14590b57cec5SDimitry Andric 14600b57cec5SDimitry Andric void addDeferredVTable(const CXXRecordDecl *RD) { 14610b57cec5SDimitry Andric DeferredVTables.push_back(RD); 14620b57cec5SDimitry Andric } 14630b57cec5SDimitry Andric 14640b57cec5SDimitry Andric /// Emit code for a single global function or var decl. Forward declarations 14650b57cec5SDimitry Andric /// are emitted lazily. 14660b57cec5SDimitry Andric void EmitGlobal(GlobalDecl D); 14670b57cec5SDimitry Andric 14680b57cec5SDimitry Andric bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D); 14690b57cec5SDimitry Andric 14700b57cec5SDimitry Andric llvm::GlobalValue *GetGlobalValue(StringRef Ref); 14710b57cec5SDimitry Andric 14720b57cec5SDimitry Andric /// Set attributes which are common to any form of a global definition (alias, 14730b57cec5SDimitry Andric /// Objective-C method, function, global variable). 14740b57cec5SDimitry Andric /// 14750b57cec5SDimitry Andric /// NOTE: This should only be called for definitions. 14760b57cec5SDimitry Andric void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV); 14770b57cec5SDimitry Andric 14780b57cec5SDimitry Andric void addReplacement(StringRef Name, llvm::Constant *C); 14790b57cec5SDimitry Andric 14800b57cec5SDimitry Andric void addGlobalValReplacement(llvm::GlobalValue *GV, llvm::Constant *C); 14810b57cec5SDimitry Andric 14820b57cec5SDimitry Andric /// Emit a code for threadprivate directive. 14830b57cec5SDimitry Andric /// \param D Threadprivate declaration. 14840b57cec5SDimitry Andric void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D); 14850b57cec5SDimitry Andric 14860b57cec5SDimitry Andric /// Emit a code for declare reduction construct. 14870b57cec5SDimitry Andric void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D, 14880b57cec5SDimitry Andric CodeGenFunction *CGF = nullptr); 14890b57cec5SDimitry Andric 14900b57cec5SDimitry Andric /// Emit a code for declare mapper construct. 14910b57cec5SDimitry Andric void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D, 14920b57cec5SDimitry Andric CodeGenFunction *CGF = nullptr); 14930b57cec5SDimitry Andric 14940b57cec5SDimitry Andric /// Emit a code for requires directive. 14950b57cec5SDimitry Andric /// \param D Requires declaration 14960b57cec5SDimitry Andric void EmitOMPRequiresDecl(const OMPRequiresDecl *D); 14970b57cec5SDimitry Andric 1498fe6060f1SDimitry Andric /// Emit a code for the allocate directive. 1499fe6060f1SDimitry Andric /// \param D The allocate declaration 1500fe6060f1SDimitry Andric void EmitOMPAllocateDecl(const OMPAllocateDecl *D); 1501fe6060f1SDimitry Andric 150281ad6265SDimitry Andric /// Return the alignment specified in an allocate directive, if present. 1503bdd1243dSDimitry Andric std::optional<CharUnits> getOMPAllocateAlignment(const VarDecl *VD); 150481ad6265SDimitry Andric 15050b57cec5SDimitry Andric /// Returns whether the given record has hidden LTO visibility and therefore 15060b57cec5SDimitry Andric /// may participate in (single-module) CFI and whole-program vtable 15070b57cec5SDimitry Andric /// optimization. 15080b57cec5SDimitry Andric bool HasHiddenLTOVisibility(const CXXRecordDecl *RD); 15090b57cec5SDimitry Andric 151081ad6265SDimitry Andric /// Returns whether the given record has public LTO visibility (regardless of 151181ad6265SDimitry Andric /// -lto-whole-program-visibility) and therefore may not participate in 151281ad6265SDimitry Andric /// (single-module) CFI and whole-program vtable optimization. 151381ad6265SDimitry Andric bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD); 15145ffd83dbSDimitry Andric 1515a7dea167SDimitry Andric /// Returns the vcall visibility of the given type. This is the scope in which 1516a7dea167SDimitry Andric /// a virtual function call could be made which ends up being dispatched to a 1517a7dea167SDimitry Andric /// member function of this class. This scope can be wider than the visibility 1518a7dea167SDimitry Andric /// of the class itself when the class has a more-visible dynamic base class. 1519e8d8bef9SDimitry Andric /// The client should pass in an empty Visited set, which is used to prevent 1520e8d8bef9SDimitry Andric /// redundant recursive processing. 1521a7dea167SDimitry Andric llvm::GlobalObject::VCallVisibility 1522e8d8bef9SDimitry Andric GetVCallVisibilityLevel(const CXXRecordDecl *RD, 1523e8d8bef9SDimitry Andric llvm::DenseSet<const CXXRecordDecl *> &Visited); 1524a7dea167SDimitry Andric 15250b57cec5SDimitry Andric /// Emit type metadata for the given vtable using the given layout. 1526a7dea167SDimitry Andric void EmitVTableTypeMetadata(const CXXRecordDecl *RD, 1527a7dea167SDimitry Andric llvm::GlobalVariable *VTable, 15280b57cec5SDimitry Andric const VTableLayout &VTLayout); 15290b57cec5SDimitry Andric 1530bdd1243dSDimitry Andric llvm::Type *getVTableComponentType() const; 1531bdd1243dSDimitry Andric 15320b57cec5SDimitry Andric /// Generate a cross-DSO type identifier for MD. 15330b57cec5SDimitry Andric llvm::ConstantInt *CreateCrossDsoCfiTypeId(llvm::Metadata *MD); 15340b57cec5SDimitry Andric 1535bdd1243dSDimitry Andric /// Generate a KCFI type identifier for T. 1536bdd1243dSDimitry Andric llvm::ConstantInt *CreateKCFITypeId(QualType T); 1537bdd1243dSDimitry Andric 15380b57cec5SDimitry Andric /// Create a metadata identifier for the given type. This may either be an 15390b57cec5SDimitry Andric /// MDString (for external identifiers) or a distinct unnamed MDNode (for 15400b57cec5SDimitry Andric /// internal identifiers). 15410b57cec5SDimitry Andric llvm::Metadata *CreateMetadataIdentifierForType(QualType T); 15420b57cec5SDimitry Andric 15430b57cec5SDimitry Andric /// Create a metadata identifier that is intended to be used to check virtual 15440b57cec5SDimitry Andric /// calls via a member function pointer. 15450b57cec5SDimitry Andric llvm::Metadata *CreateMetadataIdentifierForVirtualMemPtrType(QualType T); 15460b57cec5SDimitry Andric 15470b57cec5SDimitry Andric /// Create a metadata identifier for the generalization of the given type. 15480b57cec5SDimitry Andric /// This may either be an MDString (for external identifiers) or a distinct 15490b57cec5SDimitry Andric /// unnamed MDNode (for internal identifiers). 15500b57cec5SDimitry Andric llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T); 15510b57cec5SDimitry Andric 15520b57cec5SDimitry Andric /// Create and attach type metadata to the given function. 15530b57cec5SDimitry Andric void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD, 15540b57cec5SDimitry Andric llvm::Function *F); 15550b57cec5SDimitry Andric 1556bdd1243dSDimitry Andric /// Set type metadata to the given function. 1557bdd1243dSDimitry Andric void setKCFIType(const FunctionDecl *FD, llvm::Function *F); 1558bdd1243dSDimitry Andric 1559bdd1243dSDimitry Andric /// Emit KCFI type identifier constants and remove unused identifiers. 1560bdd1243dSDimitry Andric void finalizeKCFITypes(); 1561bdd1243dSDimitry Andric 1562fe6060f1SDimitry Andric /// Whether this function's return type has no side effects, and thus may 1563fe6060f1SDimitry Andric /// be trivially discarded if it is unused. 1564bdd1243dSDimitry Andric bool MayDropFunctionReturn(const ASTContext &Context, 1565bdd1243dSDimitry Andric QualType ReturnType) const; 1566fe6060f1SDimitry Andric 15670b57cec5SDimitry Andric /// Returns whether this module needs the "all-vtables" type identifier. 15680b57cec5SDimitry Andric bool NeedAllVtablesTypeId() const; 15690b57cec5SDimitry Andric 15700b57cec5SDimitry Andric /// Create and attach type metadata for the given vtable. 15710b57cec5SDimitry Andric void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, 15720b57cec5SDimitry Andric const CXXRecordDecl *RD); 15730b57cec5SDimitry Andric 15740b57cec5SDimitry Andric /// Return a vector of most-base classes for RD. This is used to implement 15750b57cec5SDimitry Andric /// control flow integrity checks for member function pointers. 15760b57cec5SDimitry Andric /// 15770b57cec5SDimitry Andric /// A most-base class of a class C is defined as a recursive base class of C, 15780b57cec5SDimitry Andric /// including C itself, that does not have any bases. 15795f757f3fSDimitry Andric SmallVector<const CXXRecordDecl *, 0> 15800b57cec5SDimitry Andric getMostBaseClasses(const CXXRecordDecl *RD); 15810b57cec5SDimitry Andric 15820b57cec5SDimitry Andric /// Get the declaration of std::terminate for the platform. 15830b57cec5SDimitry Andric llvm::FunctionCallee getTerminateFn(); 15840b57cec5SDimitry Andric 15850b57cec5SDimitry Andric llvm::SanitizerStatReport &getSanStats(); 15860b57cec5SDimitry Andric 15870b57cec5SDimitry Andric llvm::Value * 15880b57cec5SDimitry Andric createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF); 15890b57cec5SDimitry Andric 15900b57cec5SDimitry Andric /// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument 15910b57cec5SDimitry Andric /// information in the program executable. The argument information stored 15920b57cec5SDimitry Andric /// includes the argument name, its type, the address and access qualifiers 15930b57cec5SDimitry Andric /// used. This helper can be used to generate metadata for source code kernel 15940b57cec5SDimitry Andric /// function as well as generated implicitly kernels. If a kernel is generated 15950b57cec5SDimitry Andric /// implicitly null value has to be passed to the last two parameters, 15960b57cec5SDimitry Andric /// otherwise all parameters must have valid non-null values. 15970b57cec5SDimitry Andric /// \param FN is a pointer to IR function being generated. 15980b57cec5SDimitry Andric /// \param FD is a pointer to function declaration if any. 15990b57cec5SDimitry Andric /// \param CGF is a pointer to CodeGenFunction that generates this function. 160081ad6265SDimitry Andric void GenKernelArgMetadata(llvm::Function *FN, 16010b57cec5SDimitry Andric const FunctionDecl *FD = nullptr, 16020b57cec5SDimitry Andric CodeGenFunction *CGF = nullptr); 16030b57cec5SDimitry Andric 16040b57cec5SDimitry Andric /// Get target specific null pointer. 16050b57cec5SDimitry Andric /// \param T is the LLVM type of the null pointer. 16060b57cec5SDimitry Andric /// \param QT is the clang QualType of the null pointer. 16070b57cec5SDimitry Andric llvm::Constant *getNullPointer(llvm::PointerType *T, QualType QT); 16080b57cec5SDimitry Andric 16095ffd83dbSDimitry Andric CharUnits getNaturalTypeAlignment(QualType T, 16105ffd83dbSDimitry Andric LValueBaseInfo *BaseInfo = nullptr, 16115ffd83dbSDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr, 16125ffd83dbSDimitry Andric bool forPointeeType = false); 16135ffd83dbSDimitry Andric CharUnits getNaturalPointeeTypeAlignment(QualType T, 16145ffd83dbSDimitry Andric LValueBaseInfo *BaseInfo = nullptr, 16155ffd83dbSDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr); 16165ffd83dbSDimitry Andric bool stopAutoInit(); 16175ffd83dbSDimitry Andric 16182a66634dSDimitry Andric /// Print the postfix for externalized static variable or kernels for single 161981ad6265SDimitry Andric /// source offloading languages CUDA and HIP. The unique postfix is created 162081ad6265SDimitry Andric /// using either the CUID argument, or the file's UniqueID and active macros. 162181ad6265SDimitry Andric /// The fallback method without a CUID requires that the offloading toolchain 162281ad6265SDimitry Andric /// does not define separate macros via the -cc1 options. 16232a66634dSDimitry Andric void printPostfixForExternalizedDecl(llvm::raw_ostream &OS, 16242a66634dSDimitry Andric const Decl *D) const; 1625fe6060f1SDimitry Andric 162681ad6265SDimitry Andric /// Move some lazily-emitted states to the NewBuilder. This is especially 162781ad6265SDimitry Andric /// essential for the incremental parsing environment like Clang Interpreter, 162881ad6265SDimitry Andric /// because we'll lose all important information after each repl. 1629fcaf7f86SDimitry Andric void moveLazyEmissionStates(CodeGenModule *NewBuilder); 163081ad6265SDimitry Andric 16315f757f3fSDimitry Andric /// Emit the IR encoding to attach the CUDA launch bounds attribute to \p F. 16325f757f3fSDimitry Andric /// If \p MaxThreadsVal is not nullptr, the max threads value is stored in it, 16335f757f3fSDimitry Andric /// if a valid one was found. 16345f757f3fSDimitry Andric void handleCUDALaunchBoundsAttr(llvm::Function *F, 16355f757f3fSDimitry Andric const CUDALaunchBoundsAttr *A, 16365f757f3fSDimitry Andric int32_t *MaxThreadsVal = nullptr, 16375f757f3fSDimitry Andric int32_t *MinBlocksVal = nullptr, 16385f757f3fSDimitry Andric int32_t *MaxClusterRankVal = nullptr); 16395f757f3fSDimitry Andric 16405f757f3fSDimitry Andric /// Emit the IR encoding to attach the AMD GPU flat-work-group-size attribute 16415f757f3fSDimitry Andric /// to \p F. Alternatively, the work group size can be taken from a \p 16425f757f3fSDimitry Andric /// ReqdWGS. If \p MinThreadsVal is not nullptr, the min threads value is 16435f757f3fSDimitry Andric /// stored in it, if a valid one was found. If \p MaxThreadsVal is not 16445f757f3fSDimitry Andric /// nullptr, the max threads value is stored in it, if a valid one was found. 16455f757f3fSDimitry Andric void handleAMDGPUFlatWorkGroupSizeAttr( 16465f757f3fSDimitry Andric llvm::Function *F, const AMDGPUFlatWorkGroupSizeAttr *A, 16475f757f3fSDimitry Andric const ReqdWorkGroupSizeAttr *ReqdWGS = nullptr, 16485f757f3fSDimitry Andric int32_t *MinThreadsVal = nullptr, int32_t *MaxThreadsVal = nullptr); 16495f757f3fSDimitry Andric 16505f757f3fSDimitry Andric /// Emit the IR encoding to attach the AMD GPU waves-per-eu attribute to \p F. 16515f757f3fSDimitry Andric void handleAMDGPUWavesPerEUAttr(llvm::Function *F, 16525f757f3fSDimitry Andric const AMDGPUWavesPerEUAttr *A); 16535f757f3fSDimitry Andric 16545f757f3fSDimitry Andric llvm::Constant * 16555f757f3fSDimitry Andric GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, LangAS AddrSpace, 16565f757f3fSDimitry Andric const VarDecl *D, 16575f757f3fSDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition); 16585f757f3fSDimitry Andric 16595f757f3fSDimitry Andric // FIXME: Hardcoding priority here is gross. 16605f757f3fSDimitry Andric void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535, 16615f757f3fSDimitry Andric unsigned LexOrder = ~0U, 16625f757f3fSDimitry Andric llvm::Constant *AssociatedData = nullptr); 16635f757f3fSDimitry Andric void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535, 16645f757f3fSDimitry Andric bool IsDtorAttrFunc = false); 16655f757f3fSDimitry Andric 16660fca6ea1SDimitry Andric // Return whether structured convergence intrinsics should be generated for 16670fca6ea1SDimitry Andric // this target. 16680fca6ea1SDimitry Andric bool shouldEmitConvergenceTokens() const { 16690fca6ea1SDimitry Andric // TODO: this should probably become unconditional once the controlled 16700fca6ea1SDimitry Andric // convergence becomes the norm. 16710fca6ea1SDimitry Andric return getTriple().isSPIRVLogical(); 16720fca6ea1SDimitry Andric } 16730fca6ea1SDimitry Andric 16740fca6ea1SDimitry Andric void addUndefinedGlobalForTailCall( 16750fca6ea1SDimitry Andric std::pair<const FunctionDecl *, SourceLocation> Global) { 16760fca6ea1SDimitry Andric MustTailCallUndefinedGlobals.insert(Global); 16770fca6ea1SDimitry Andric } 16780fca6ea1SDimitry Andric 16790b57cec5SDimitry Andric private: 16800fca6ea1SDimitry Andric bool shouldDropDLLAttribute(const Decl *D, const llvm::GlobalValue *GV) const; 16810fca6ea1SDimitry Andric 16820b57cec5SDimitry Andric llvm::Constant *GetOrCreateLLVMFunction( 16830b57cec5SDimitry Andric StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable, 16840b57cec5SDimitry Andric bool DontDefer = false, bool IsThunk = false, 16850b57cec5SDimitry Andric llvm::AttributeList ExtraAttrs = llvm::AttributeList(), 16860b57cec5SDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition); 16870b57cec5SDimitry Andric 16880fca6ea1SDimitry Andric // Adds a declaration to the list of multi version functions if not present. 16890fca6ea1SDimitry Andric void AddDeferredMultiVersionResolverToEmit(GlobalDecl GD); 16900fca6ea1SDimitry Andric 169181ad6265SDimitry Andric // References to multiversion functions are resolved through an implicitly 169281ad6265SDimitry Andric // defined resolver function. This function is responsible for creating 169381ad6265SDimitry Andric // the resolver symbol for the provided declaration. The value returned 169481ad6265SDimitry Andric // will be for an ifunc (llvm::GlobalIFunc) if the current target supports 169581ad6265SDimitry Andric // that feature and for a regular function (llvm::GlobalValue) otherwise. 169681ad6265SDimitry Andric llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD); 169781ad6265SDimitry Andric 169881ad6265SDimitry Andric // In scenarios where a function is not known to be a multiversion function 169981ad6265SDimitry Andric // until a later declaration, it is sometimes necessary to change the 170081ad6265SDimitry Andric // previously created mangled name to align with requirements of whatever 170181ad6265SDimitry Andric // multiversion function kind the function is now known to be. This function 170281ad6265SDimitry Andric // is responsible for performing such mangled name updates. 170304eeddc0SDimitry Andric void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD, 170404eeddc0SDimitry Andric StringRef &CurName); 17050b57cec5SDimitry Andric 17060b57cec5SDimitry Andric bool GetCPUAndFeaturesAttributes(GlobalDecl GD, 170706c3fb27SDimitry Andric llvm::AttrBuilder &AttrBuilder, 170806c3fb27SDimitry Andric bool SetTargetFeatures = true); 17090b57cec5SDimitry Andric void setNonAliasAttributes(GlobalDecl GD, llvm::GlobalObject *GO); 17100b57cec5SDimitry Andric 17110b57cec5SDimitry Andric /// Set function attributes for a function declaration. 17120b57cec5SDimitry Andric void SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, 17130b57cec5SDimitry Andric bool IsIncompleteFunction, bool IsThunk); 17140b57cec5SDimitry Andric 17150b57cec5SDimitry Andric void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr); 17160b57cec5SDimitry Andric 17170b57cec5SDimitry Andric void EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV); 17180b57cec5SDimitry Andric void EmitMultiVersionFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV); 17190b57cec5SDimitry Andric 17200b57cec5SDimitry Andric void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false); 1721480093f4SDimitry Andric void EmitExternalVarDeclaration(const VarDecl *D); 17220fca6ea1SDimitry Andric void EmitExternalFunctionDeclaration(const FunctionDecl *D); 17230b57cec5SDimitry Andric void EmitAliasDefinition(GlobalDecl GD); 17240b57cec5SDimitry Andric void emitIFuncDefinition(GlobalDecl GD); 17250b57cec5SDimitry Andric void emitCPUDispatchDefinition(GlobalDecl GD); 17260b57cec5SDimitry Andric void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); 17270b57cec5SDimitry Andric void EmitObjCIvarInitializations(ObjCImplementationDecl *D); 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andric // C++ related functions. 17300b57cec5SDimitry Andric 17310b57cec5SDimitry Andric void EmitDeclContext(const DeclContext *DC); 17320b57cec5SDimitry Andric void EmitLinkageSpec(const LinkageSpecDecl *D); 1733bdd1243dSDimitry Andric void EmitTopLevelStmt(const TopLevelStmtDecl *D); 17340b57cec5SDimitry Andric 17350b57cec5SDimitry Andric /// Emit the function that initializes C++ thread_local variables. 17360b57cec5SDimitry Andric void EmitCXXThreadLocalInitFunc(); 17370b57cec5SDimitry Andric 1738fcaf7f86SDimitry Andric /// Emit the function that initializes global variables for a C++ Module. 1739fcaf7f86SDimitry Andric void EmitCXXModuleInitFunc(clang::Module *Primary); 1740fcaf7f86SDimitry Andric 17410b57cec5SDimitry Andric /// Emit the function that initializes C++ globals. 17420b57cec5SDimitry Andric void EmitCXXGlobalInitFunc(); 17430b57cec5SDimitry Andric 17445ffd83dbSDimitry Andric /// Emit the function that performs cleanup associated with C++ globals. 17455ffd83dbSDimitry Andric void EmitCXXGlobalCleanUpFunc(); 17460b57cec5SDimitry Andric 17470b57cec5SDimitry Andric /// Emit the function that initializes the specified global (if PerformInit is 17480b57cec5SDimitry Andric /// true) and registers its destructor. 17490b57cec5SDimitry Andric void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, 17500b57cec5SDimitry Andric llvm::GlobalVariable *Addr, 17510b57cec5SDimitry Andric bool PerformInit); 17520b57cec5SDimitry Andric 17530b57cec5SDimitry Andric void EmitPointerToInitFunc(const VarDecl *VD, llvm::GlobalVariable *Addr, 17540b57cec5SDimitry Andric llvm::Function *InitFunc, InitSegAttr *ISA); 17550b57cec5SDimitry Andric 17560b57cec5SDimitry Andric /// EmitCtorList - Generates a global array of functions and priorities using 17570b57cec5SDimitry Andric /// the given list and name. This array will have appending linkage and is 17580b57cec5SDimitry Andric /// suitable for use as a LLVM constructor or destructor array. Clears Fns. 17590b57cec5SDimitry Andric void EmitCtorList(CtorList &Fns, const char *GlobalName); 17600b57cec5SDimitry Andric 17610b57cec5SDimitry Andric /// Emit any needed decls for which code generation was deferred. 17620b57cec5SDimitry Andric void EmitDeferred(); 17630b57cec5SDimitry Andric 17640b57cec5SDimitry Andric /// Try to emit external vtables as available_externally if they have emitted 17650b57cec5SDimitry Andric /// all inlined virtual functions. It runs after EmitDeferred() and therefore 17660b57cec5SDimitry Andric /// is not allowed to create new references to things that need to be emitted 17670b57cec5SDimitry Andric /// lazily. 17680b57cec5SDimitry Andric void EmitVTablesOpportunistically(); 17690b57cec5SDimitry Andric 17700b57cec5SDimitry Andric /// Call replaceAllUsesWith on all pairs in Replacements. 17710b57cec5SDimitry Andric void applyReplacements(); 17720b57cec5SDimitry Andric 17730b57cec5SDimitry Andric /// Call replaceAllUsesWith on all pairs in GlobalValReplacements. 17740b57cec5SDimitry Andric void applyGlobalValReplacements(); 17750b57cec5SDimitry Andric 17760b57cec5SDimitry Andric void checkAliases(); 17770b57cec5SDimitry Andric 17780b57cec5SDimitry Andric std::map<int, llvm::TinyPtrVector<llvm::Function *>> DtorsUsingAtExit; 17790b57cec5SDimitry Andric 17800b57cec5SDimitry Andric /// Register functions annotated with __attribute__((destructor)) using 17810b57cec5SDimitry Andric /// __cxa_atexit, if it is available, or atexit otherwise. 17820b57cec5SDimitry Andric void registerGlobalDtorsWithAtExit(); 17830b57cec5SDimitry Andric 1784e8d8bef9SDimitry Andric // When using sinit and sterm functions, unregister 1785e8d8bef9SDimitry Andric // __attribute__((destructor)) annotated functions which were previously 1786e8d8bef9SDimitry Andric // registered by the atexit subroutine using unatexit. 1787e8d8bef9SDimitry Andric void unregisterGlobalDtorsWithUnAtExit(); 1788e8d8bef9SDimitry Andric 178981ad6265SDimitry Andric /// Emit deferred multiversion function resolvers and associated variants. 17900b57cec5SDimitry Andric void emitMultiVersionFunctions(); 17910b57cec5SDimitry Andric 17920b57cec5SDimitry Andric /// Emit any vtables which we deferred and still have a use for. 17930b57cec5SDimitry Andric void EmitDeferredVTables(); 17940b57cec5SDimitry Andric 17950b57cec5SDimitry Andric /// Emit a dummy function that reference a CoreFoundation symbol when 17960b57cec5SDimitry Andric /// @available is used on Darwin. 17970b57cec5SDimitry Andric void emitAtAvailableLinkGuard(); 17980b57cec5SDimitry Andric 17990b57cec5SDimitry Andric /// Emit the llvm.used and llvm.compiler.used metadata. 18000b57cec5SDimitry Andric void emitLLVMUsed(); 18010b57cec5SDimitry Andric 1802fcaf7f86SDimitry Andric /// For C++20 Itanium ABI, emit the initializers for the module. 1803fcaf7f86SDimitry Andric void EmitModuleInitializers(clang::Module *Primary); 1804fcaf7f86SDimitry Andric 18050b57cec5SDimitry Andric /// Emit the link options introduced by imported modules. 18060b57cec5SDimitry Andric void EmitModuleLinkOptions(); 18070b57cec5SDimitry Andric 180881ad6265SDimitry Andric /// Helper function for EmitStaticExternCAliases() to redirect ifuncs that 180981ad6265SDimitry Andric /// have a resolver name that matches 'Elem' to instead resolve to the name of 181081ad6265SDimitry Andric /// 'CppFunc'. This redirection is necessary in cases where 'Elem' has a name 181181ad6265SDimitry Andric /// that will be emitted as an alias of the name bound to 'CppFunc'; ifuncs 181281ad6265SDimitry Andric /// may not reference aliases. Redirection is only performed if 'Elem' is only 181381ad6265SDimitry Andric /// used by ifuncs in which case, 'Elem' is destroyed. 'true' is returned if 181481ad6265SDimitry Andric /// redirection is successful, and 'false' is returned otherwise. 181581ad6265SDimitry Andric bool CheckAndReplaceExternCIFuncs(llvm::GlobalValue *Elem, 181681ad6265SDimitry Andric llvm::GlobalValue *CppFunc); 181781ad6265SDimitry Andric 18180b57cec5SDimitry Andric /// Emit aliases for internal-linkage declarations inside "C" language 18190b57cec5SDimitry Andric /// linkage specifications, giving them the "expected" name where possible. 18200b57cec5SDimitry Andric void EmitStaticExternCAliases(); 18210b57cec5SDimitry Andric 18220b57cec5SDimitry Andric void EmitDeclMetadata(); 18230b57cec5SDimitry Andric 18240b57cec5SDimitry Andric /// Emit the Clang version as llvm.ident metadata. 18250b57cec5SDimitry Andric void EmitVersionIdentMetadata(); 18260b57cec5SDimitry Andric 18270b57cec5SDimitry Andric /// Emit the Clang commandline as llvm.commandline metadata. 18280b57cec5SDimitry Andric void EmitCommandLineMetadata(); 18290b57cec5SDimitry Andric 18305ffd83dbSDimitry Andric /// Emit the module flag metadata used to pass options controlling the 18315ffd83dbSDimitry Andric /// the backend to LLVM. 183206c3fb27SDimitry Andric void EmitBackendOptionsMetadata(const CodeGenOptions &CodeGenOpts); 18330b57cec5SDimitry Andric 18340b57cec5SDimitry Andric /// Emits OpenCL specific Metadata e.g. OpenCL version. 18350b57cec5SDimitry Andric void EmitOpenCLMetadata(); 18360b57cec5SDimitry Andric 18370b57cec5SDimitry Andric /// Emit the llvm.gcov metadata used to tell LLVM where to emit the .gcno and 18380b57cec5SDimitry Andric /// .gcda files in a way that persists in .bc files. 18390b57cec5SDimitry Andric void EmitCoverageFile(); 18400b57cec5SDimitry Andric 18410b57cec5SDimitry Andric /// Determine whether the definition must be emitted; if this returns \c 18420b57cec5SDimitry Andric /// false, the definition can be emitted lazily if it's used. 18430b57cec5SDimitry Andric bool MustBeEmitted(const ValueDecl *D); 18440b57cec5SDimitry Andric 18450b57cec5SDimitry Andric /// Determine whether the definition can be emitted eagerly, or should be 18460b57cec5SDimitry Andric /// delayed until the end of the translation unit. This is relevant for 18470b57cec5SDimitry Andric /// definitions whose linkage can change, e.g. implicit function instantions 18480b57cec5SDimitry Andric /// which may later be explicitly instantiated. 18490b57cec5SDimitry Andric bool MayBeEmittedEagerly(const ValueDecl *D); 18500b57cec5SDimitry Andric 18510b57cec5SDimitry Andric /// Check whether we can use a "simpler", more core exceptions personality 18520b57cec5SDimitry Andric /// function. 18530b57cec5SDimitry Andric void SimplifyPersonality(); 18540b57cec5SDimitry Andric 185506c3fb27SDimitry Andric /// Helper function for getDefaultFunctionAttributes. Builds a set of function 185606c3fb27SDimitry Andric /// attributes which can be simply added to a function. 185706c3fb27SDimitry Andric void getTrivialDefaultFunctionAttributes(StringRef Name, bool HasOptnone, 185806c3fb27SDimitry Andric bool AttrOnCallSite, 185906c3fb27SDimitry Andric llvm::AttrBuilder &FuncAttrs); 186006c3fb27SDimitry Andric 18615ffd83dbSDimitry Andric /// Helper function for ConstructAttributeList and 18625ffd83dbSDimitry Andric /// addDefaultFunctionDefinitionAttributes. Builds a set of function 18635ffd83dbSDimitry Andric /// attributes to add to a function with the given properties. 18645ffd83dbSDimitry Andric void getDefaultFunctionAttributes(StringRef Name, bool HasOptnone, 18650b57cec5SDimitry Andric bool AttrOnCallSite, 18660b57cec5SDimitry Andric llvm::AttrBuilder &FuncAttrs); 18670b57cec5SDimitry Andric 18680b57cec5SDimitry Andric llvm::Metadata *CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map, 18690b57cec5SDimitry Andric StringRef Suffix); 18700b57cec5SDimitry Andric }; 18710b57cec5SDimitry Andric 18720b57cec5SDimitry Andric } // end namespace CodeGen 18730b57cec5SDimitry Andric } // end namespace clang 18740b57cec5SDimitry Andric 18750b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H 1876