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" 270b57cec5SDimitry Andric #include "clang/Basic/Module.h" 28fe6060f1SDimitry Andric #include "clang/Basic/NoSanitizeList.h" 29c9157d92SDimitry Andric #include "clang/Basic/ProfileList.h" 305ffd83dbSDimitry Andric #include "clang/Basic/TargetInfo.h" 310b57cec5SDimitry Andric #include "clang/Basic/XRayLists.h" 32fe6060f1SDimitry Andric #include "clang/Lex/PreprocessorOptions.h" 330b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 34fe013be4SDimitry Andric #include "llvm/ADT/MapVector.h" 350b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 360b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 370b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h" 380b57cec5SDimitry Andric #include "llvm/IR/Module.h" 390b57cec5SDimitry Andric #include "llvm/IR/ValueHandle.h" 400b57cec5SDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h" 41bdd1243dSDimitry Andric #include <optional> 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric namespace llvm { 440b57cec5SDimitry Andric class Module; 450b57cec5SDimitry Andric class Constant; 460b57cec5SDimitry Andric class ConstantInt; 470b57cec5SDimitry Andric class Function; 480b57cec5SDimitry Andric class GlobalValue; 490b57cec5SDimitry Andric class DataLayout; 500b57cec5SDimitry Andric class FunctionType; 510b57cec5SDimitry Andric class LLVMContext; 520b57cec5SDimitry Andric class IndexedInstrProfReader; 53972a253aSDimitry Andric 54972a253aSDimitry Andric namespace vfs { 55972a253aSDimitry Andric class FileSystem; 56972a253aSDimitry Andric } 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric namespace clang { 600b57cec5SDimitry Andric class ASTContext; 610b57cec5SDimitry Andric class AtomicType; 620b57cec5SDimitry Andric class FunctionDecl; 630b57cec5SDimitry Andric class IdentifierInfo; 640b57cec5SDimitry Andric class ObjCImplementationDecl; 650b57cec5SDimitry Andric class ObjCEncodeExpr; 660b57cec5SDimitry Andric class BlockExpr; 670b57cec5SDimitry Andric class CharUnits; 680b57cec5SDimitry Andric class Decl; 690b57cec5SDimitry Andric class Expr; 700b57cec5SDimitry Andric class Stmt; 710b57cec5SDimitry Andric class StringLiteral; 720b57cec5SDimitry Andric class NamedDecl; 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; OrderGlobalInitsOrStermFinalizersOrderGlobalInitsOrStermFinalizers107fe6060f1SDimitry 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 { ObjCEntrypointsObjCEntrypoints1210b57cec5SDimitry 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 { 218c9157d92SDimitry Andric uint32_t VisitedInMainFile = 0; 219c9157d92SDimitry Andric uint32_t MissingInMainFile = 0; 220c9157d92SDimitry Andric uint32_t Visited = 0; 221c9157d92SDimitry Andric uint32_t Missing = 0; 222c9157d92SDimitry Andric uint32_t Mismatched = 0; 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric public: 225c9157d92SDimitry 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. addVisited(bool MainFile)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. addMissing(bool MainFile)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. addMismatched(bool MainFile)2400b57cec5SDimitry Andric void addMismatched(bool MainFile) { ++Mismatched; } 2410b57cec5SDimitry Andric /// Whether or not the stats we've gathered indicate any potential problems. hasDiagnostics()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 BlockByrefHelpers(CharUnits alignment)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 Profile(llvm::FoldingSetNodeID & id)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 needsCopy()2710b57cec5SDimitry Andric virtual bool needsCopy() const { return true; } 2720b57cec5SDimitry Andric virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src) = 0; 2730b57cec5SDimitry Andric needsDispose()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 { StructorStructor286bdd1243dSDimitry Andric Structor() 287bdd1243dSDimitry Andric : Priority(0), LexOrder(~0u), Initializer(nullptr), 288bdd1243dSDimitry Andric AssociatedData(nullptr) {} StructorStructor289bdd1243dSDimitry 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 3230b57cec5SDimitry Andric 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 3510b57cec5SDimitry Andric /// This is a list of deferred decls which we have seen that *are* actually 3520b57cec5SDimitry Andric /// referenced. These get code generated when the module is done. 3530b57cec5SDimitry Andric std::vector<GlobalDecl> DeferredDeclsToEmit; addDeferredDeclToEmit(GlobalDecl GD)3540b57cec5SDimitry Andric void addDeferredDeclToEmit(GlobalDecl GD) { 3550b57cec5SDimitry Andric DeferredDeclsToEmit.emplace_back(GD); 356753f127fSDimitry Andric addEmittedDeferredDecl(GD); 357753f127fSDimitry Andric } 358753f127fSDimitry Andric 359753f127fSDimitry Andric /// Decls that were DeferredDecls and have now been emitted. 360753f127fSDimitry Andric llvm::DenseMap<llvm::StringRef, GlobalDecl> EmittedDeferredDecls; 361753f127fSDimitry Andric addEmittedDeferredDecl(GlobalDecl GD)362753f127fSDimitry Andric void addEmittedDeferredDecl(GlobalDecl GD) { 363271697daSDimitry Andric // Reemission is only needed in incremental mode. 364271697daSDimitry Andric if (!Context.getLangOpts().IncrementalExtensions) 365753f127fSDimitry Andric return; 366271697daSDimitry Andric 367271697daSDimitry Andric // Assume a linkage by default that does not need reemission. 368271697daSDimitry Andric auto L = llvm::GlobalValue::ExternalLinkage; 369271697daSDimitry Andric if (llvm::isa<FunctionDecl>(GD.getDecl())) 370271697daSDimitry Andric L = getFunctionLinkage(GD); 371271697daSDimitry Andric else if (auto *VD = llvm::dyn_cast<VarDecl>(GD.getDecl())) 372271697daSDimitry Andric L = getLLVMLinkageVarDefinition(VD); 373271697daSDimitry Andric 374271697daSDimitry Andric if (llvm::GlobalValue::isInternalLinkage(L) || 375271697daSDimitry Andric llvm::GlobalValue::isLinkOnceLinkage(L) || 376753f127fSDimitry Andric llvm::GlobalValue::isWeakLinkage(L)) { 377753f127fSDimitry Andric EmittedDeferredDecls[getMangledName(GD)] = GD; 378753f127fSDimitry Andric } 3790b57cec5SDimitry Andric } 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric /// List of alias we have emitted. Used to make sure that what they point to 3820b57cec5SDimitry Andric /// is defined once we get to the end of the of the translation unit. 3830b57cec5SDimitry Andric std::vector<GlobalDecl> Aliases; 3840b57cec5SDimitry Andric 38581ad6265SDimitry Andric /// List of multiversion functions to be emitted. This list is processed in 38681ad6265SDimitry Andric /// conjunction with other deferred symbols and is used to ensure that 38781ad6265SDimitry Andric /// multiversion function resolvers and ifuncs are defined and emitted. 3880b57cec5SDimitry Andric std::vector<GlobalDecl> MultiVersionFuncs; 3890b57cec5SDimitry Andric 390fe013be4SDimitry Andric llvm::MapVector<StringRef, llvm::TrackingVH<llvm::Constant>> Replacements; 3910b57cec5SDimitry Andric 3920b57cec5SDimitry Andric /// List of global values to be replaced with something else. Used when we 3930b57cec5SDimitry Andric /// want to replace a GlobalValue but can't identify it by its mangled name 3940b57cec5SDimitry Andric /// anymore (because the name is already taken). 3950b57cec5SDimitry Andric llvm::SmallVector<std::pair<llvm::GlobalValue *, llvm::Constant *>, 8> 3960b57cec5SDimitry Andric GlobalValReplacements; 3970b57cec5SDimitry Andric 3980b57cec5SDimitry Andric /// Variables for which we've emitted globals containing their constant 3990b57cec5SDimitry Andric /// values along with the corresponding globals, for opportunistic reuse. 4000b57cec5SDimitry Andric llvm::DenseMap<const VarDecl*, llvm::GlobalVariable*> InitializerConstants; 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric /// Set of global decls for which we already diagnosed mangled name conflict. 4030b57cec5SDimitry Andric /// Required to not issue a warning (on a mangling conflict) multiple times 4040b57cec5SDimitry Andric /// for the same decl. 4050b57cec5SDimitry Andric llvm::DenseSet<GlobalDecl> DiagnosedConflictingDefinitions; 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric /// A queue of (optional) vtables to consider emitting. 4080b57cec5SDimitry Andric std::vector<const CXXRecordDecl*> DeferredVTables; 4090b57cec5SDimitry Andric 4100b57cec5SDimitry Andric /// A queue of (optional) vtables that may be emitted opportunistically. 4110b57cec5SDimitry Andric std::vector<const CXXRecordDecl *> OpportunisticVTables; 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric /// List of global values which are required to be present in the object file; 4140b57cec5SDimitry Andric /// bitcast to i8*. This is used for forcing visibility of symbols which may 4150b57cec5SDimitry Andric /// otherwise be optimized out. 4160b57cec5SDimitry Andric std::vector<llvm::WeakTrackingVH> LLVMUsed; 4170b57cec5SDimitry Andric std::vector<llvm::WeakTrackingVH> LLVMCompilerUsed; 4180b57cec5SDimitry Andric 4190b57cec5SDimitry Andric /// Store the list of global constructors and their respective priorities to 4200b57cec5SDimitry Andric /// be emitted when the translation unit is complete. 4210b57cec5SDimitry Andric CtorList GlobalCtors; 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric /// Store the list of global destructors and their respective priorities to be 4240b57cec5SDimitry Andric /// emitted when the translation unit is complete. 4250b57cec5SDimitry Andric CtorList GlobalDtors; 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric /// An ordered map of canonical GlobalDecls to their mangled names. 4280b57cec5SDimitry Andric llvm::MapVector<GlobalDecl, StringRef> MangledDeclNames; 4290b57cec5SDimitry Andric llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings; 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric /// Global annotations. 4320b57cec5SDimitry Andric std::vector<llvm::Constant*> Annotations; 4330b57cec5SDimitry Andric 434c9157d92SDimitry Andric // Store deferred function annotations so they can be emitted at the end with 435c9157d92SDimitry Andric // most up to date ValueDecl that will have all the inherited annotations. 436c9157d92SDimitry Andric llvm::DenseMap<StringRef, const ValueDecl *> DeferredAnnotations; 437c9157d92SDimitry Andric 4380b57cec5SDimitry Andric /// Map used to get unique annotation strings. 4390b57cec5SDimitry Andric llvm::StringMap<llvm::Constant*> AnnotationStrings; 4400b57cec5SDimitry Andric 441e8d8bef9SDimitry Andric /// Used for uniquing of annotation arguments. 442e8d8bef9SDimitry Andric llvm::DenseMap<unsigned, llvm::Constant *> AnnotationArgs; 443e8d8bef9SDimitry Andric 4440b57cec5SDimitry Andric llvm::StringMap<llvm::GlobalVariable *> CFConstantStringMap; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> ConstantStringMap; 44781ad6265SDimitry Andric llvm::DenseMap<const UnnamedGlobalConstantDecl *, llvm::GlobalVariable *> 44881ad6265SDimitry Andric UnnamedGlobalConstantDeclMap; 4490b57cec5SDimitry Andric llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap; 4500b57cec5SDimitry Andric llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap; 4510b57cec5SDimitry Andric llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap; 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap; 4540b57cec5SDimitry Andric llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap; 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric /// Map used to get unique type descriptor constants for sanitizers. 4570b57cec5SDimitry Andric llvm::DenseMap<QualType, llvm::Constant *> TypeDescriptorMap; 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric /// Map used to track internal linkage functions declared within 4600b57cec5SDimitry Andric /// extern "C" regions. 4610b57cec5SDimitry Andric typedef llvm::MapVector<IdentifierInfo *, 4620b57cec5SDimitry Andric llvm::GlobalValue *> StaticExternCMap; 4630b57cec5SDimitry Andric StaticExternCMap StaticExternCValues; 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric /// thread_local variables defined or used in this TU. 4660b57cec5SDimitry Andric std::vector<const VarDecl *> CXXThreadLocals; 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric /// thread_local variables with initializers that need to run 4690b57cec5SDimitry Andric /// before any thread_local variable in this TU is odr-used. 4700b57cec5SDimitry Andric std::vector<llvm::Function *> CXXThreadLocalInits; 4710b57cec5SDimitry Andric std::vector<const VarDecl *> CXXThreadLocalInitVars; 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric /// Global variables with initializers that need to run before main. 4740b57cec5SDimitry Andric std::vector<llvm::Function *> CXXGlobalInits; 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric /// When a C++ decl with an initializer is deferred, null is 4770b57cec5SDimitry Andric /// appended to CXXGlobalInits, and the index of that null is placed 4780b57cec5SDimitry Andric /// here so that the initializer will be performed in the correct 4790b57cec5SDimitry Andric /// order. Once the decl is emitted, the index is replaced with ~0U to ensure 4800b57cec5SDimitry Andric /// that we don't re-emit the initializer. 4810b57cec5SDimitry Andric llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition; 4820b57cec5SDimitry Andric 483fe6060f1SDimitry Andric typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *> 484fe6060f1SDimitry Andric GlobalInitData; 4850b57cec5SDimitry Andric 4860b57cec5SDimitry Andric struct GlobalInitPriorityCmp { operatorGlobalInitPriorityCmp4870b57cec5SDimitry Andric bool operator()(const GlobalInitData &LHS, 4880b57cec5SDimitry Andric const GlobalInitData &RHS) const { 4890b57cec5SDimitry Andric return LHS.first.priority < RHS.first.priority; 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric }; 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric /// Global variables with initializers whose order of initialization is set by 4940b57cec5SDimitry Andric /// init_priority attribute. 4950b57cec5SDimitry Andric SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits; 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric /// Global destructor functions and arguments that need to run on termination. 4985ffd83dbSDimitry Andric /// When UseSinitAndSterm is set, it instead contains sterm finalizer 4995ffd83dbSDimitry Andric /// functions, which also run on unloading a shared library. 500fe6060f1SDimitry Andric typedef std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH, 501fe6060f1SDimitry Andric llvm::Constant *> 502fe6060f1SDimitry Andric CXXGlobalDtorsOrStermFinalizer_t; 503fe6060f1SDimitry Andric SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8> 5045ffd83dbSDimitry Andric CXXGlobalDtorsOrStermFinalizers; 5050b57cec5SDimitry Andric 506fe6060f1SDimitry Andric typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *> 507fe6060f1SDimitry Andric StermFinalizerData; 508fe6060f1SDimitry Andric 509fe6060f1SDimitry Andric struct StermFinalizerPriorityCmp { operatorStermFinalizerPriorityCmp510fe6060f1SDimitry Andric bool operator()(const StermFinalizerData &LHS, 511fe6060f1SDimitry Andric const StermFinalizerData &RHS) const { 512fe6060f1SDimitry Andric return LHS.first.priority < RHS.first.priority; 513fe6060f1SDimitry Andric } 514fe6060f1SDimitry Andric }; 515fe6060f1SDimitry Andric 516fe6060f1SDimitry Andric /// Global variables with sterm finalizers whose order of initialization is 517fe6060f1SDimitry Andric /// set by init_priority attribute. 518fe6060f1SDimitry Andric SmallVector<StermFinalizerData, 8> PrioritizedCXXStermFinalizers; 519fe6060f1SDimitry Andric 5200b57cec5SDimitry Andric /// The complete set of modules that has been imported. 5210b57cec5SDimitry Andric llvm::SetVector<clang::Module *> ImportedModules; 5220b57cec5SDimitry Andric 5230b57cec5SDimitry Andric /// The set of modules for which the module initializers 5240b57cec5SDimitry Andric /// have been emitted. 5250b57cec5SDimitry Andric llvm::SmallPtrSet<clang::Module *, 16> EmittedModuleInitializers; 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric /// A vector of metadata strings for linker options. 5280b57cec5SDimitry Andric SmallVector<llvm::MDNode *, 16> LinkerOptionsMetadata; 5290b57cec5SDimitry Andric 5300b57cec5SDimitry Andric /// A vector of metadata strings for dependent libraries for ELF. 5310b57cec5SDimitry Andric SmallVector<llvm::MDNode *, 16> ELFDependentLibraries; 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric /// @name Cache for Objective-C runtime types 5340b57cec5SDimitry Andric /// @{ 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric /// Cached reference to the class for constant strings. This value has type 5370b57cec5SDimitry Andric /// int * but is actually an Obj-C class pointer. 5380b57cec5SDimitry Andric llvm::WeakTrackingVH CFConstantStringClassRef; 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric /// The type used to describe the state of a fast enumeration in 5410b57cec5SDimitry Andric /// Objective-C's for..in loop. 5420b57cec5SDimitry Andric QualType ObjCFastEnumerationStateType; 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric /// @} 5450b57cec5SDimitry Andric 5460b57cec5SDimitry Andric /// Lazily create the Objective-C runtime 5470b57cec5SDimitry Andric void createObjCRuntime(); 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric void createOpenCLRuntime(); 5500b57cec5SDimitry Andric void createOpenMPRuntime(); 5510b57cec5SDimitry Andric void createCUDARuntime(); 55281ad6265SDimitry Andric void createHLSLRuntime(); 5530b57cec5SDimitry Andric 5540b57cec5SDimitry Andric bool isTriviallyRecursive(const FunctionDecl *F); 5550b57cec5SDimitry Andric bool shouldEmitFunction(GlobalDecl GD); 5560b57cec5SDimitry Andric bool shouldOpportunisticallyEmitVTables(); 5570b57cec5SDimitry Andric /// Map used to be sure we don't emit the same CompoundLiteral twice. 5580b57cec5SDimitry Andric llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *> 5590b57cec5SDimitry Andric EmittedCompoundLiterals; 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric /// Map of the global blocks we've emitted, so that we don't have to re-emit 5620b57cec5SDimitry Andric /// them if the constexpr evaluator gets aggressive. 5630b57cec5SDimitry Andric llvm::DenseMap<const BlockExpr *, llvm::Constant *> EmittedGlobalBlocks; 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andric /// @name Cache for Blocks Runtime Globals 5660b57cec5SDimitry Andric /// @{ 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric llvm::Constant *NSConcreteGlobalBlock = nullptr; 5690b57cec5SDimitry Andric llvm::Constant *NSConcreteStackBlock = nullptr; 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric llvm::FunctionCallee BlockObjectAssign = nullptr; 5720b57cec5SDimitry Andric llvm::FunctionCallee BlockObjectDispose = nullptr; 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric llvm::Type *BlockDescriptorType = nullptr; 5750b57cec5SDimitry Andric llvm::Type *GenericBlockLiteralType = nullptr; 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric struct { 5780b57cec5SDimitry Andric int GlobalUniqueCount; 5790b57cec5SDimitry Andric } Block; 5800b57cec5SDimitry Andric 581480093f4SDimitry Andric GlobalDecl initializedGlobalDecl; 582480093f4SDimitry Andric 583480093f4SDimitry Andric /// @} 584480093f4SDimitry Andric 5850b57cec5SDimitry Andric /// void @llvm.lifetime.start(i64 %size, i8* nocapture <ptr>) 5860b57cec5SDimitry Andric llvm::Function *LifetimeStartFn = nullptr; 5870b57cec5SDimitry Andric 5880b57cec5SDimitry Andric /// void @llvm.lifetime.end(i64 %size, i8* nocapture <ptr>) 5890b57cec5SDimitry Andric llvm::Function *LifetimeEndFn = nullptr; 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric std::unique_ptr<SanitizerMetadata> SanitizerMD; 5920b57cec5SDimitry Andric 5930b57cec5SDimitry Andric llvm::MapVector<const Decl *, bool> DeferredEmptyCoverageMappingDecls; 5940b57cec5SDimitry Andric 5950b57cec5SDimitry Andric std::unique_ptr<CoverageMappingModuleGen> CoverageMapping; 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric /// Mapping from canonical types to their metadata identifiers. We need to 5980b57cec5SDimitry Andric /// maintain this mapping because identifiers may be formed from distinct 5990b57cec5SDimitry Andric /// MDNodes. 6000b57cec5SDimitry Andric typedef llvm::DenseMap<QualType, llvm::Metadata *> MetadataTypeMap; 6010b57cec5SDimitry Andric MetadataTypeMap MetadataIdMap; 6020b57cec5SDimitry Andric MetadataTypeMap VirtualMetadataIdMap; 6030b57cec5SDimitry Andric MetadataTypeMap GeneralizedMetadataIdMap; 6040b57cec5SDimitry Andric 605bdd1243dSDimitry Andric // Helps squashing blocks of TopLevelStmtDecl into a single llvm::Function 606bdd1243dSDimitry Andric // when used with -fincremental-extensions. 607bdd1243dSDimitry Andric std::pair<std::unique_ptr<CodeGenFunction>, const TopLevelStmtDecl *> 608bdd1243dSDimitry Andric GlobalTopLevelStmtBlockInFlight; 609bdd1243dSDimitry Andric 6100b57cec5SDimitry Andric public: 611972a253aSDimitry Andric CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, 612972a253aSDimitry Andric const HeaderSearchOptions &headersearchopts, 6130b57cec5SDimitry Andric const PreprocessorOptions &ppopts, 6140b57cec5SDimitry Andric const CodeGenOptions &CodeGenOpts, llvm::Module &M, 6150b57cec5SDimitry Andric DiagnosticsEngine &Diags, 6160b57cec5SDimitry Andric CoverageSourceInfo *CoverageInfo = nullptr); 6170b57cec5SDimitry Andric 6180b57cec5SDimitry Andric ~CodeGenModule(); 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric void clear(); 6210b57cec5SDimitry Andric 6220b57cec5SDimitry Andric /// Finalize LLVM code generation. 6230b57cec5SDimitry Andric void Release(); 6240b57cec5SDimitry Andric 6250b57cec5SDimitry Andric /// Return true if we should emit location information for expressions. 6260b57cec5SDimitry Andric bool getExpressionLocationsEnabled() const; 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andric /// Return a reference to the configured Objective-C runtime. getObjCRuntime()6290b57cec5SDimitry Andric CGObjCRuntime &getObjCRuntime() { 6300b57cec5SDimitry Andric if (!ObjCRuntime) createObjCRuntime(); 6310b57cec5SDimitry Andric return *ObjCRuntime; 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric 6340b57cec5SDimitry Andric /// Return true iff an Objective-C runtime has been configured. hasObjCRuntime()6350b57cec5SDimitry Andric bool hasObjCRuntime() { return !!ObjCRuntime; } 6360b57cec5SDimitry Andric getModuleNameHash()637fe6060f1SDimitry Andric const std::string &getModuleNameHash() const { return ModuleNameHash; } 638fe6060f1SDimitry Andric 6390b57cec5SDimitry Andric /// Return a reference to the configured OpenCL runtime. getOpenCLRuntime()6400b57cec5SDimitry Andric CGOpenCLRuntime &getOpenCLRuntime() { 6410b57cec5SDimitry Andric assert(OpenCLRuntime != nullptr); 6420b57cec5SDimitry Andric return *OpenCLRuntime; 6430b57cec5SDimitry Andric } 6440b57cec5SDimitry Andric 6450b57cec5SDimitry Andric /// Return a reference to the configured OpenMP runtime. getOpenMPRuntime()6460b57cec5SDimitry Andric CGOpenMPRuntime &getOpenMPRuntime() { 6470b57cec5SDimitry Andric assert(OpenMPRuntime != nullptr); 6480b57cec5SDimitry Andric return *OpenMPRuntime; 6490b57cec5SDimitry Andric } 6500b57cec5SDimitry Andric 6510b57cec5SDimitry Andric /// Return a reference to the configured CUDA runtime. getCUDARuntime()6520b57cec5SDimitry Andric CGCUDARuntime &getCUDARuntime() { 6530b57cec5SDimitry Andric assert(CUDARuntime != nullptr); 6540b57cec5SDimitry Andric return *CUDARuntime; 6550b57cec5SDimitry Andric } 6560b57cec5SDimitry Andric 65781ad6265SDimitry Andric /// Return a reference to the configured HLSL runtime. getHLSLRuntime()65881ad6265SDimitry Andric CGHLSLRuntime &getHLSLRuntime() { 65981ad6265SDimitry Andric assert(HLSLRuntime != nullptr); 66081ad6265SDimitry Andric return *HLSLRuntime; 66181ad6265SDimitry Andric } 66281ad6265SDimitry Andric getObjCEntrypoints()6630b57cec5SDimitry Andric ObjCEntrypoints &getObjCEntrypoints() const { 6640b57cec5SDimitry Andric assert(ObjCData != nullptr); 6650b57cec5SDimitry Andric return *ObjCData; 6660b57cec5SDimitry Andric } 6670b57cec5SDimitry Andric 668e8d8bef9SDimitry Andric // Version checking functions, used to implement ObjC's @available: 6690b57cec5SDimitry Andric // i32 @__isOSVersionAtLeast(i32, i32, i32) 6700b57cec5SDimitry Andric llvm::FunctionCallee IsOSVersionAtLeastFn = nullptr; 671e8d8bef9SDimitry Andric // i32 @__isPlatformVersionAtLeast(i32, i32, i32, i32) 672e8d8bef9SDimitry Andric llvm::FunctionCallee IsPlatformVersionAtLeastFn = nullptr; 6730b57cec5SDimitry Andric getPGOStats()6740b57cec5SDimitry Andric InstrProfStats &getPGOStats() { return PGOStats; } getPGOReader()6750b57cec5SDimitry Andric llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); } 6760b57cec5SDimitry Andric getCoverageMapping()6770b57cec5SDimitry Andric CoverageMappingModuleGen *getCoverageMapping() const { 6780b57cec5SDimitry Andric return CoverageMapping.get(); 6790b57cec5SDimitry Andric } 6800b57cec5SDimitry Andric getStaticLocalDeclAddress(const VarDecl * D)6810b57cec5SDimitry Andric llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) { 6820b57cec5SDimitry Andric return StaticLocalDeclMap[D]; 6830b57cec5SDimitry Andric } setStaticLocalDeclAddress(const VarDecl * D,llvm::Constant * C)6840b57cec5SDimitry Andric void setStaticLocalDeclAddress(const VarDecl *D, 6850b57cec5SDimitry Andric llvm::Constant *C) { 6860b57cec5SDimitry Andric StaticLocalDeclMap[D] = C; 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric 6890b57cec5SDimitry Andric llvm::Constant * 6900b57cec5SDimitry Andric getOrCreateStaticVarDecl(const VarDecl &D, 6910b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage); 6920b57cec5SDimitry Andric getStaticLocalDeclGuardAddress(const VarDecl * D)6930b57cec5SDimitry Andric llvm::GlobalVariable *getStaticLocalDeclGuardAddress(const VarDecl *D) { 6940b57cec5SDimitry Andric return StaticLocalDeclGuardMap[D]; 6950b57cec5SDimitry Andric } setStaticLocalDeclGuardAddress(const VarDecl * D,llvm::GlobalVariable * C)6960b57cec5SDimitry Andric void setStaticLocalDeclGuardAddress(const VarDecl *D, 6970b57cec5SDimitry Andric llvm::GlobalVariable *C) { 6980b57cec5SDimitry Andric StaticLocalDeclGuardMap[D] = C; 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant, 7020b57cec5SDimitry Andric CharUnits Align); 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric bool lookupRepresentativeDecl(StringRef MangledName, 7050b57cec5SDimitry Andric GlobalDecl &Result) const; 7060b57cec5SDimitry Andric getAtomicSetterHelperFnMap(QualType Ty)7070b57cec5SDimitry Andric llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) { 7080b57cec5SDimitry Andric return AtomicSetterHelperFnMap[Ty]; 7090b57cec5SDimitry Andric } setAtomicSetterHelperFnMap(QualType Ty,llvm::Constant * Fn)7100b57cec5SDimitry Andric void setAtomicSetterHelperFnMap(QualType Ty, 7110b57cec5SDimitry Andric llvm::Constant *Fn) { 7120b57cec5SDimitry Andric AtomicSetterHelperFnMap[Ty] = Fn; 7130b57cec5SDimitry Andric } 7140b57cec5SDimitry Andric getAtomicGetterHelperFnMap(QualType Ty)7150b57cec5SDimitry Andric llvm::Constant *getAtomicGetterHelperFnMap(QualType Ty) { 7160b57cec5SDimitry Andric return AtomicGetterHelperFnMap[Ty]; 7170b57cec5SDimitry Andric } setAtomicGetterHelperFnMap(QualType Ty,llvm::Constant * Fn)7180b57cec5SDimitry Andric void setAtomicGetterHelperFnMap(QualType Ty, 7190b57cec5SDimitry Andric llvm::Constant *Fn) { 7200b57cec5SDimitry Andric AtomicGetterHelperFnMap[Ty] = Fn; 7210b57cec5SDimitry Andric } 7220b57cec5SDimitry Andric getTypeDescriptorFromMap(QualType Ty)7230b57cec5SDimitry Andric llvm::Constant *getTypeDescriptorFromMap(QualType Ty) { 7240b57cec5SDimitry Andric return TypeDescriptorMap[Ty]; 7250b57cec5SDimitry Andric } setTypeDescriptorInMap(QualType Ty,llvm::Constant * C)7260b57cec5SDimitry Andric void setTypeDescriptorInMap(QualType Ty, llvm::Constant *C) { 7270b57cec5SDimitry Andric TypeDescriptorMap[Ty] = C; 7280b57cec5SDimitry Andric } 7290b57cec5SDimitry Andric getModuleDebugInfo()7300b57cec5SDimitry Andric CGDebugInfo *getModuleDebugInfo() { return DebugInfo.get(); } 7310b57cec5SDimitry Andric getNoObjCARCExceptionsMetadata()7320b57cec5SDimitry Andric llvm::MDNode *getNoObjCARCExceptionsMetadata() { 7330b57cec5SDimitry Andric if (!NoObjCARCExceptionsMetadata) 734bdd1243dSDimitry Andric NoObjCARCExceptionsMetadata = 735bdd1243dSDimitry Andric llvm::MDNode::get(getLLVMContext(), std::nullopt); 7360b57cec5SDimitry Andric return NoObjCARCExceptionsMetadata; 7370b57cec5SDimitry Andric } 7380b57cec5SDimitry Andric getContext()7390b57cec5SDimitry Andric ASTContext &getContext() const { return Context; } getLangOpts()7400b57cec5SDimitry Andric const LangOptions &getLangOpts() const { return LangOpts; } getFileSystem()741972a253aSDimitry Andric const IntrusiveRefCntPtr<llvm::vfs::FileSystem> &getFileSystem() const { 742972a253aSDimitry Andric return FS; 743972a253aSDimitry Andric } getHeaderSearchOpts()7440b57cec5SDimitry Andric const HeaderSearchOptions &getHeaderSearchOpts() 7450b57cec5SDimitry Andric const { return HeaderSearchOpts; } getPreprocessorOpts()7460b57cec5SDimitry Andric const PreprocessorOptions &getPreprocessorOpts() 7470b57cec5SDimitry Andric const { return PreprocessorOpts; } getCodeGenOpts()7480b57cec5SDimitry Andric const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; } getModule()7490b57cec5SDimitry Andric llvm::Module &getModule() const { return TheModule; } getDiags()7500b57cec5SDimitry Andric DiagnosticsEngine &getDiags() const { return Diags; } getDataLayout()7510b57cec5SDimitry Andric const llvm::DataLayout &getDataLayout() const { 7520b57cec5SDimitry Andric return TheModule.getDataLayout(); 7530b57cec5SDimitry Andric } getTarget()7540b57cec5SDimitry Andric const TargetInfo &getTarget() const { return Target; } getTriple()7550b57cec5SDimitry Andric const llvm::Triple &getTriple() const { return Target.getTriple(); } 7560b57cec5SDimitry Andric bool supportsCOMDAT() const; 7570b57cec5SDimitry Andric void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO); 7580b57cec5SDimitry Andric getCXXABI()7590b57cec5SDimitry Andric CGCXXABI &getCXXABI() const { return *ABI; } getLLVMContext()7600b57cec5SDimitry Andric llvm::LLVMContext &getLLVMContext() { return VMContext; } 7610b57cec5SDimitry Andric shouldUseTBAA()7620b57cec5SDimitry Andric bool shouldUseTBAA() const { return TBAA != nullptr; } 7630b57cec5SDimitry Andric 7640b57cec5SDimitry Andric const TargetCodeGenInfo &getTargetCodeGenInfo(); 7650b57cec5SDimitry Andric getTypes()7660b57cec5SDimitry Andric CodeGenTypes &getTypes() { return Types; } 7670b57cec5SDimitry Andric getVTables()7680b57cec5SDimitry Andric CodeGenVTables &getVTables() { return VTables; } 7690b57cec5SDimitry Andric getItaniumVTableContext()7700b57cec5SDimitry Andric ItaniumVTableContext &getItaniumVTableContext() { 7710b57cec5SDimitry Andric return VTables.getItaniumVTableContext(); 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric getItaniumVTableContext()774bdd1243dSDimitry Andric const ItaniumVTableContext &getItaniumVTableContext() const { 775bdd1243dSDimitry Andric return VTables.getItaniumVTableContext(); 776bdd1243dSDimitry Andric } 777bdd1243dSDimitry Andric getMicrosoftVTableContext()7780b57cec5SDimitry Andric MicrosoftVTableContext &getMicrosoftVTableContext() { 7790b57cec5SDimitry Andric return VTables.getMicrosoftVTableContext(); 7800b57cec5SDimitry Andric } 7810b57cec5SDimitry Andric getGlobalCtors()7820b57cec5SDimitry Andric CtorList &getGlobalCtors() { return GlobalCtors; } getGlobalDtors()7830b57cec5SDimitry Andric CtorList &getGlobalDtors() { return GlobalDtors; } 7840b57cec5SDimitry Andric 7850b57cec5SDimitry Andric /// getTBAATypeInfo - Get metadata used to describe accesses to objects of 7860b57cec5SDimitry Andric /// the given type. 7870b57cec5SDimitry Andric llvm::MDNode *getTBAATypeInfo(QualType QTy); 7880b57cec5SDimitry Andric 7890b57cec5SDimitry Andric /// getTBAAAccessInfo - Get TBAA information that describes an access to 7900b57cec5SDimitry Andric /// an object of the given type. 7910b57cec5SDimitry Andric TBAAAccessInfo getTBAAAccessInfo(QualType AccessType); 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an 7940b57cec5SDimitry Andric /// access to a virtual table pointer. 7950b57cec5SDimitry Andric TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType); 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric llvm::MDNode *getTBAAStructInfo(QualType QTy); 7980b57cec5SDimitry Andric 7990b57cec5SDimitry Andric /// getTBAABaseTypeInfo - Get metadata that describes the given base access 8000b57cec5SDimitry Andric /// type. Return null if the type is not suitable for use in TBAA access tags. 8010b57cec5SDimitry Andric llvm::MDNode *getTBAABaseTypeInfo(QualType QTy); 8020b57cec5SDimitry Andric 8030b57cec5SDimitry Andric /// getTBAAAccessTagInfo - Get TBAA tag for a given memory access. 8040b57cec5SDimitry Andric llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info); 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of 8070b57cec5SDimitry Andric /// type casts. 8080b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo, 8090b57cec5SDimitry Andric TBAAAccessInfo TargetInfo); 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the 8120b57cec5SDimitry Andric /// purposes of conditional operator. 8130b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA, 8140b57cec5SDimitry Andric TBAAAccessInfo InfoB); 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric /// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the 8170b57cec5SDimitry Andric /// purposes of memory transfer calls. 8180b57cec5SDimitry Andric TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo, 8190b57cec5SDimitry Andric TBAAAccessInfo SrcInfo); 8200b57cec5SDimitry Andric 8210b57cec5SDimitry Andric /// getTBAAInfoForSubobject - Get TBAA information for an access with a given 8220b57cec5SDimitry Andric /// base lvalue. getTBAAInfoForSubobject(LValue Base,QualType AccessType)8230b57cec5SDimitry Andric TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType) { 8240b57cec5SDimitry Andric if (Base.getTBAAInfo().isMayAlias()) 8250b57cec5SDimitry Andric return TBAAAccessInfo::getMayAliasInfo(); 8260b57cec5SDimitry Andric return getTBAAAccessInfo(AccessType); 8270b57cec5SDimitry Andric } 8280b57cec5SDimitry Andric 8290b57cec5SDimitry Andric bool isPaddedAtomicType(QualType type); 8300b57cec5SDimitry Andric bool isPaddedAtomicType(const AtomicType *type); 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric /// DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag. 8330b57cec5SDimitry Andric void DecorateInstructionWithTBAA(llvm::Instruction *Inst, 8340b57cec5SDimitry Andric TBAAAccessInfo TBAAInfo); 8350b57cec5SDimitry Andric 8360b57cec5SDimitry Andric /// Adds !invariant.barrier !tag to instruction 8370b57cec5SDimitry Andric void DecorateInstructionWithInvariantGroup(llvm::Instruction *I, 8380b57cec5SDimitry Andric const CXXRecordDecl *RD); 8390b57cec5SDimitry Andric 8400b57cec5SDimitry Andric /// Emit the given number of characters as a value of type size_t. 8410b57cec5SDimitry Andric llvm::ConstantInt *getSize(CharUnits numChars); 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andric /// Set the visibility for the given LLVM GlobalValue. 8440b57cec5SDimitry Andric void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const; 8450b57cec5SDimitry Andric 8460b57cec5SDimitry Andric void setDSOLocal(llvm::GlobalValue *GV) const; 8470b57cec5SDimitry Andric shouldMapVisibilityToDLLExport(const NamedDecl * D)84881ad6265SDimitry Andric bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const { 84981ad6265SDimitry Andric return getLangOpts().hasDefaultVisibilityExportMapping() && D && 85081ad6265SDimitry Andric (D->getLinkageAndVisibility().getVisibility() == 85181ad6265SDimitry Andric DefaultVisibility) && 85281ad6265SDimitry Andric (getLangOpts().isAllDefaultVisibilityExportMapping() || 85381ad6265SDimitry Andric (getLangOpts().isExplicitDefaultVisibilityExportMapping() && 85481ad6265SDimitry Andric D->getLinkageAndVisibility().isVisibilityExplicit())); 85581ad6265SDimitry Andric } 8560b57cec5SDimitry Andric void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const; 8570b57cec5SDimitry Andric void setDLLImportDLLExport(llvm::GlobalValue *GV, const NamedDecl *D) const; 8580b57cec5SDimitry Andric /// Set visibility, dllimport/dllexport and dso_local. 8590b57cec5SDimitry Andric /// This must be called after dllimport/dllexport is set. 8600b57cec5SDimitry Andric void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const; 8610b57cec5SDimitry Andric void setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D) const; 8620b57cec5SDimitry Andric 8630b57cec5SDimitry Andric void setGVPropertiesAux(llvm::GlobalValue *GV, const NamedDecl *D) const; 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric /// Set the TLS mode for the given LLVM GlobalValue for the thread-local 8660b57cec5SDimitry Andric /// variable declaration D. 8670b57cec5SDimitry Andric void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const; 8680b57cec5SDimitry Andric 8695ffd83dbSDimitry Andric /// Get LLVM TLS mode from CodeGenOptions. 8705ffd83dbSDimitry Andric llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const; 8715ffd83dbSDimitry Andric GetLLVMVisibility(Visibility V)8720b57cec5SDimitry Andric static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) { 8730b57cec5SDimitry Andric switch (V) { 8740b57cec5SDimitry Andric case DefaultVisibility: return llvm::GlobalValue::DefaultVisibility; 8750b57cec5SDimitry Andric case HiddenVisibility: return llvm::GlobalValue::HiddenVisibility; 8760b57cec5SDimitry Andric case ProtectedVisibility: return llvm::GlobalValue::ProtectedVisibility; 8770b57cec5SDimitry Andric } 8780b57cec5SDimitry Andric llvm_unreachable("unknown visibility!"); 8790b57cec5SDimitry Andric } 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric llvm::Constant *GetAddrOfGlobal(GlobalDecl GD, 8820b57cec5SDimitry Andric ForDefinition_t IsForDefinition 8830b57cec5SDimitry Andric = NotForDefinition); 8840b57cec5SDimitry Andric 8850b57cec5SDimitry Andric /// Will return a global variable of the given type. If a variable with a 8860b57cec5SDimitry Andric /// different type already exists then a new variable with the right type 8870b57cec5SDimitry Andric /// will be created and all uses of the old variable will be replaced with a 8880b57cec5SDimitry Andric /// bitcast to the new variable. 8890b57cec5SDimitry Andric llvm::GlobalVariable * 8900b57cec5SDimitry Andric CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty, 8910b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes Linkage, 892bdd1243dSDimitry Andric llvm::Align Alignment); 8930b57cec5SDimitry Andric 8945ffd83dbSDimitry Andric llvm::Function *CreateGlobalInitOrCleanUpFunction( 8955ffd83dbSDimitry Andric llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI, 89681ad6265SDimitry Andric SourceLocation Loc = SourceLocation(), bool TLS = false, 89781ad6265SDimitry Andric llvm::GlobalVariable::LinkageTypes Linkage = 89881ad6265SDimitry Andric llvm::GlobalVariable::InternalLinkage); 8990b57cec5SDimitry Andric 9000b57cec5SDimitry Andric /// Return the AST address space of the underlying global variable for D, as 9010b57cec5SDimitry Andric /// determined by its declaration. Normally this is the same as the address 9020b57cec5SDimitry Andric /// space of D's type, but in CUDA, address spaces are associated with 9030b57cec5SDimitry Andric /// declarations, not types. If D is nullptr, return the default address 9040b57cec5SDimitry Andric /// space for global variable. 9050b57cec5SDimitry Andric /// 9060b57cec5SDimitry Andric /// For languages without explicit address spaces, if D has default address 9070b57cec5SDimitry Andric /// space, target-specific global or constant address space may be returned. 9080b57cec5SDimitry Andric LangAS GetGlobalVarAddressSpace(const VarDecl *D); 9090b57cec5SDimitry Andric 910fe6060f1SDimitry Andric /// Return the AST address space of constant literal, which is used to emit 911fe6060f1SDimitry Andric /// the constant literal as global variable in LLVM IR. 912fe6060f1SDimitry Andric /// Note: This is not necessarily the address space of the constant literal 913fe6060f1SDimitry Andric /// in AST. For address space agnostic language, e.g. C++, constant literal 914fe6060f1SDimitry Andric /// in AST is always in default address space. 915fe6060f1SDimitry Andric LangAS GetGlobalConstantAddressSpace() const; 916fe6060f1SDimitry Andric 9170b57cec5SDimitry Andric /// Return the llvm::Constant for the address of the given global variable. 9180b57cec5SDimitry Andric /// If Ty is non-null and if the global doesn't exist, then it will be created 9190b57cec5SDimitry Andric /// with the specified type instead of whatever the normal requested type 9200b57cec5SDimitry Andric /// would be. If IsForDefinition is true, it is guaranteed that an actual 9210b57cec5SDimitry Andric /// global with type Ty will be returned, not conversion of a variable with 9220b57cec5SDimitry Andric /// the same mangled name but some other type. 9230b57cec5SDimitry Andric llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D, 9240b57cec5SDimitry Andric llvm::Type *Ty = nullptr, 9250b57cec5SDimitry Andric ForDefinition_t IsForDefinition 9260b57cec5SDimitry Andric = NotForDefinition); 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric /// Return the address of the given function. If Ty is non-null, then this 9290b57cec5SDimitry Andric /// function will use the specified type if it has to create it. 9300b57cec5SDimitry Andric llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = nullptr, 9310b57cec5SDimitry Andric bool ForVTable = false, 9320b57cec5SDimitry Andric bool DontDefer = false, 9330b57cec5SDimitry Andric ForDefinition_t IsForDefinition 9340b57cec5SDimitry Andric = NotForDefinition); 9350b57cec5SDimitry Andric 9360eae32dcSDimitry Andric // Return the function body address of the given function. 9370eae32dcSDimitry Andric llvm::Constant *GetFunctionStart(const ValueDecl *Decl); 9380eae32dcSDimitry Andric 939fe013be4SDimitry Andric // Return whether RTTI information should be emitted for this target. 940fe013be4SDimitry Andric bool shouldEmitRTTI(bool ForEH = false) { 941fe013be4SDimitry Andric return (ForEH || getLangOpts().RTTI) && !getLangOpts().CUDAIsDevice && 942fe013be4SDimitry Andric !(getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice && 943fe013be4SDimitry Andric getTriple().isNVPTX()); 944fe013be4SDimitry Andric } 945fe013be4SDimitry Andric 9460b57cec5SDimitry Andric /// Get the address of the RTTI descriptor for the given type. 9470b57cec5SDimitry Andric llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false); 9480b57cec5SDimitry Andric 9495ffd83dbSDimitry Andric /// Get the address of a GUID. 9505ffd83dbSDimitry Andric ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD); 9510b57cec5SDimitry Andric 95281ad6265SDimitry Andric /// Get the address of a UnnamedGlobalConstant 95381ad6265SDimitry Andric ConstantAddress 95481ad6265SDimitry Andric GetAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *GCD); 95581ad6265SDimitry Andric 956e8d8bef9SDimitry Andric /// Get the address of a template parameter object. 957e8d8bef9SDimitry Andric ConstantAddress 958e8d8bef9SDimitry Andric GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO); 959e8d8bef9SDimitry Andric 9600b57cec5SDimitry Andric /// Get the address of the thunk for the given global decl. 9610b57cec5SDimitry Andric llvm::Constant *GetAddrOfThunk(StringRef Name, llvm::Type *FnTy, 9620b57cec5SDimitry Andric GlobalDecl GD); 9630b57cec5SDimitry Andric 9640b57cec5SDimitry Andric /// Get a reference to the target of VD. 9650b57cec5SDimitry Andric ConstantAddress GetWeakRefReference(const ValueDecl *VD); 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric /// Returns the assumed alignment of an opaque pointer to the given class. 9680b57cec5SDimitry Andric CharUnits getClassPointerAlignment(const CXXRecordDecl *CD); 9690b57cec5SDimitry Andric 9705ffd83dbSDimitry Andric /// Returns the minimum object size for an object of the given class type 9715ffd83dbSDimitry Andric /// (or a class derived from it). 9725ffd83dbSDimitry Andric CharUnits getMinimumClassObjectSize(const CXXRecordDecl *CD); 9735ffd83dbSDimitry Andric 9745ffd83dbSDimitry Andric /// Returns the minimum object size for an object of the given type. getMinimumObjectSize(QualType Ty)9755ffd83dbSDimitry Andric CharUnits getMinimumObjectSize(QualType Ty) { 9765ffd83dbSDimitry Andric if (CXXRecordDecl *RD = Ty->getAsCXXRecordDecl()) 9775ffd83dbSDimitry Andric return getMinimumClassObjectSize(RD); 9785ffd83dbSDimitry Andric return getContext().getTypeSizeInChars(Ty); 9795ffd83dbSDimitry Andric } 9805ffd83dbSDimitry Andric 9810b57cec5SDimitry Andric /// Returns the assumed alignment of a virtual base of a class. 9820b57cec5SDimitry Andric CharUnits getVBaseAlignment(CharUnits DerivedAlign, 9830b57cec5SDimitry Andric const CXXRecordDecl *Derived, 9840b57cec5SDimitry Andric const CXXRecordDecl *VBase); 9850b57cec5SDimitry Andric 9860b57cec5SDimitry Andric /// Given a class pointer with an actual known alignment, and the 9870b57cec5SDimitry Andric /// expected alignment of an object at a dynamic offset w.r.t that 9880b57cec5SDimitry Andric /// pointer, return the alignment to assume at the offset. 9890b57cec5SDimitry Andric CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign, 9900b57cec5SDimitry Andric const CXXRecordDecl *Class, 9910b57cec5SDimitry Andric CharUnits ExpectedTargetAlign); 9920b57cec5SDimitry Andric 9930b57cec5SDimitry Andric CharUnits 9940b57cec5SDimitry Andric computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass, 9950b57cec5SDimitry Andric CastExpr::path_const_iterator Start, 9960b57cec5SDimitry Andric CastExpr::path_const_iterator End); 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric /// Returns the offset from a derived class to a class. Returns null if the 9990b57cec5SDimitry Andric /// offset is 0. 10000b57cec5SDimitry Andric llvm::Constant * 10010b57cec5SDimitry Andric GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl, 10020b57cec5SDimitry Andric CastExpr::path_const_iterator PathBegin, 10030b57cec5SDimitry Andric CastExpr::path_const_iterator PathEnd); 10040b57cec5SDimitry Andric 10050b57cec5SDimitry Andric llvm::FoldingSet<BlockByrefHelpers> ByrefHelpersCache; 10060b57cec5SDimitry Andric 10070b57cec5SDimitry Andric /// Fetches the global unique block count. getUniqueBlockCount()10080b57cec5SDimitry Andric int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; } 10090b57cec5SDimitry Andric 10100b57cec5SDimitry Andric /// Fetches the type of a generic block descriptor. 10110b57cec5SDimitry Andric llvm::Type *getBlockDescriptorType(); 10120b57cec5SDimitry Andric 10130b57cec5SDimitry Andric /// The type of a generic block literal. 10140b57cec5SDimitry Andric llvm::Type *getGenericBlockLiteralType(); 10150b57cec5SDimitry Andric 10160b57cec5SDimitry Andric /// Gets the address of a block which requires no captures. 10170b57cec5SDimitry Andric llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name); 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric /// Returns the address of a block which requires no caputres, or null if 10200b57cec5SDimitry Andric /// we've yet to emit the block for BE. getAddrOfGlobalBlockIfEmitted(const BlockExpr * BE)10210b57cec5SDimitry Andric llvm::Constant *getAddrOfGlobalBlockIfEmitted(const BlockExpr *BE) { 10220b57cec5SDimitry Andric return EmittedGlobalBlocks.lookup(BE); 10230b57cec5SDimitry Andric } 10240b57cec5SDimitry Andric 10250b57cec5SDimitry Andric /// Notes that BE's global block is available via Addr. Asserts that BE 10260b57cec5SDimitry Andric /// isn't already emitted. 10270b57cec5SDimitry Andric void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr); 10280b57cec5SDimitry Andric 10290b57cec5SDimitry Andric /// Return a pointer to a constant CFString object for the given string. 10300b57cec5SDimitry Andric ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal); 10310b57cec5SDimitry Andric 10320b57cec5SDimitry Andric /// Return a constant array for the given string. 10330b57cec5SDimitry Andric llvm::Constant *GetConstantArrayFromStringLiteral(const StringLiteral *E); 10340b57cec5SDimitry Andric 10350b57cec5SDimitry Andric /// Return a pointer to a constant array for the given string literal. 10360b57cec5SDimitry Andric ConstantAddress 10370b57cec5SDimitry Andric GetAddrOfConstantStringFromLiteral(const StringLiteral *S, 10380b57cec5SDimitry Andric StringRef Name = ".str"); 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric /// Return a pointer to a constant array for the given ObjCEncodeExpr node. 10410b57cec5SDimitry Andric ConstantAddress 10420b57cec5SDimitry Andric GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *); 10430b57cec5SDimitry Andric 10440b57cec5SDimitry Andric /// Returns a pointer to a character array containing the literal and a 10450b57cec5SDimitry Andric /// terminating '\0' character. The result has pointer to array type. 10460b57cec5SDimitry Andric /// 10470b57cec5SDimitry Andric /// \param GlobalName If provided, the name to use for the global (if one is 10480b57cec5SDimitry Andric /// created). 10490b57cec5SDimitry Andric ConstantAddress 10500b57cec5SDimitry Andric GetAddrOfConstantCString(const std::string &Str, 10510b57cec5SDimitry Andric const char *GlobalName = nullptr); 10520b57cec5SDimitry Andric 10530b57cec5SDimitry Andric /// Returns a pointer to a constant global variable for the given file-scope 10540b57cec5SDimitry Andric /// compound literal expression. 10550b57cec5SDimitry Andric ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E); 10560b57cec5SDimitry Andric 10570b57cec5SDimitry Andric /// If it's been emitted already, returns the GlobalVariable corresponding to 10580b57cec5SDimitry Andric /// a compound literal. Otherwise, returns null. 10590b57cec5SDimitry Andric llvm::GlobalVariable * 10600b57cec5SDimitry Andric getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E); 10610b57cec5SDimitry Andric 10620b57cec5SDimitry Andric /// Notes that CLE's GlobalVariable is GV. Asserts that CLE isn't already 10630b57cec5SDimitry Andric /// emitted. 10640b57cec5SDimitry Andric void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE, 10650b57cec5SDimitry Andric llvm::GlobalVariable *GV); 10660b57cec5SDimitry Andric 10670b57cec5SDimitry Andric /// Returns a pointer to a global variable representing a temporary 10680b57cec5SDimitry Andric /// with static or thread storage duration. 10690b57cec5SDimitry Andric ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E, 10700b57cec5SDimitry Andric const Expr *Inner); 10710b57cec5SDimitry Andric 10720b57cec5SDimitry Andric /// Retrieve the record type that describes the state of an 10730b57cec5SDimitry Andric /// Objective-C fast enumeration loop (for..in). 10740b57cec5SDimitry Andric QualType getObjCFastEnumerationStateType(); 10750b57cec5SDimitry Andric 10760b57cec5SDimitry Andric // Produce code for this constructor/destructor. This method doesn't try 10770b57cec5SDimitry Andric // to apply any ABI rules about which other constructors/destructors 10780b57cec5SDimitry Andric // are needed or if they are alias to each other. 10790b57cec5SDimitry Andric llvm::Function *codegenCXXStructor(GlobalDecl GD); 10800b57cec5SDimitry Andric 10810b57cec5SDimitry Andric /// Return the address of the constructor/destructor of the given type. 10820b57cec5SDimitry Andric llvm::Constant * 10830b57cec5SDimitry Andric getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr, 10840b57cec5SDimitry Andric llvm::FunctionType *FnType = nullptr, 10850b57cec5SDimitry Andric bool DontDefer = false, 10860b57cec5SDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition) { 10870b57cec5SDimitry Andric return cast<llvm::Constant>(getAddrAndTypeOfCXXStructor(GD, FnInfo, FnType, 10880b57cec5SDimitry Andric DontDefer, 10890b57cec5SDimitry Andric IsForDefinition) 10900b57cec5SDimitry Andric .getCallee()); 10910b57cec5SDimitry Andric } 10920b57cec5SDimitry Andric 10930b57cec5SDimitry Andric llvm::FunctionCallee getAddrAndTypeOfCXXStructor( 10940b57cec5SDimitry Andric GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr, 10950b57cec5SDimitry Andric llvm::FunctionType *FnType = nullptr, bool DontDefer = false, 10960b57cec5SDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition); 10970b57cec5SDimitry Andric 10980b57cec5SDimitry Andric /// Given a builtin id for a function like "__builtin_fabsf", return a 10990b57cec5SDimitry Andric /// Function* for "fabsf". 11000b57cec5SDimitry Andric llvm::Constant *getBuiltinLibFunction(const FunctionDecl *FD, 11010b57cec5SDimitry Andric unsigned BuiltinID); 11020b57cec5SDimitry Andric 1103bdd1243dSDimitry Andric llvm::Function *getIntrinsic(unsigned IID, 1104bdd1243dSDimitry Andric ArrayRef<llvm::Type *> Tys = std::nullopt); 11050b57cec5SDimitry Andric 11060b57cec5SDimitry Andric /// Emit code for a single top level declaration. 11070b57cec5SDimitry Andric void EmitTopLevelDecl(Decl *D); 11080b57cec5SDimitry Andric 11090b57cec5SDimitry Andric /// Stored a deferred empty coverage mapping for an unused 11100b57cec5SDimitry Andric /// and thus uninstrumented top level declaration. 11110b57cec5SDimitry Andric void AddDeferredUnusedCoverageMapping(Decl *D); 11120b57cec5SDimitry Andric 11130b57cec5SDimitry Andric /// Remove the deferred empty coverage mapping as this 11140b57cec5SDimitry Andric /// declaration is actually instrumented. 11150b57cec5SDimitry Andric void ClearUnusedCoverageMapping(const Decl *D); 11160b57cec5SDimitry Andric 11170b57cec5SDimitry Andric /// Emit all the deferred coverage mappings 11180b57cec5SDimitry Andric /// for the uninstrumented functions. 11190b57cec5SDimitry Andric void EmitDeferredUnusedCoverageMappings(); 11200b57cec5SDimitry Andric 11215ffd83dbSDimitry Andric /// Emit an alias for "main" if it has no arguments (needed for wasm). 11225ffd83dbSDimitry Andric void EmitMainVoidAlias(); 11235ffd83dbSDimitry Andric 11240b57cec5SDimitry Andric /// Tell the consumer that this variable has been instantiated. 11250b57cec5SDimitry Andric void HandleCXXStaticMemberVarInstantiation(VarDecl *VD); 11260b57cec5SDimitry Andric 11270b57cec5SDimitry Andric /// If the declaration has internal linkage but is inside an 11280b57cec5SDimitry Andric /// extern "C" linkage specification, prepare to emit an alias for it 11290b57cec5SDimitry Andric /// to the expected name. 11300b57cec5SDimitry Andric template<typename SomeDecl> 11310b57cec5SDimitry Andric void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV); 11320b57cec5SDimitry Andric 11330b57cec5SDimitry Andric /// Add a global to a list to be added to the llvm.used metadata. 11340b57cec5SDimitry Andric void addUsedGlobal(llvm::GlobalValue *GV); 11350b57cec5SDimitry Andric 11360b57cec5SDimitry Andric /// Add a global to a list to be added to the llvm.compiler.used metadata. 11370b57cec5SDimitry Andric void addCompilerUsedGlobal(llvm::GlobalValue *GV); 11380b57cec5SDimitry Andric 1139fe6060f1SDimitry Andric /// Add a global to a list to be added to the llvm.compiler.used metadata. 1140fe6060f1SDimitry Andric void addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV); 1141fe6060f1SDimitry Andric 11420b57cec5SDimitry Andric /// Add a destructor and object to add to the C++ global destructor function. AddCXXDtorEntry(llvm::FunctionCallee DtorFn,llvm::Constant * Object)11430b57cec5SDimitry Andric void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object) { 11445ffd83dbSDimitry Andric CXXGlobalDtorsOrStermFinalizers.emplace_back(DtorFn.getFunctionType(), 11455ffd83dbSDimitry Andric DtorFn.getCallee(), Object); 11465ffd83dbSDimitry Andric } 11475ffd83dbSDimitry Andric 11485ffd83dbSDimitry Andric /// Add an sterm finalizer to the C++ global cleanup function. AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn)11495ffd83dbSDimitry Andric void AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn) { 11505ffd83dbSDimitry Andric CXXGlobalDtorsOrStermFinalizers.emplace_back(DtorFn.getFunctionType(), 11515ffd83dbSDimitry Andric DtorFn.getCallee(), nullptr); 11520b57cec5SDimitry Andric } 11530b57cec5SDimitry Andric 1154e8d8bef9SDimitry Andric /// Add an sterm finalizer to its own llvm.global_dtors entry. AddCXXStermFinalizerToGlobalDtor(llvm::Function * StermFinalizer,int Priority)1155e8d8bef9SDimitry Andric void AddCXXStermFinalizerToGlobalDtor(llvm::Function *StermFinalizer, 1156e8d8bef9SDimitry Andric int Priority) { 1157e8d8bef9SDimitry Andric AddGlobalDtor(StermFinalizer, Priority); 1158e8d8bef9SDimitry Andric } 1159e8d8bef9SDimitry Andric AddCXXPrioritizedStermFinalizerEntry(llvm::Function * StermFinalizer,int Priority)1160fe6060f1SDimitry Andric void AddCXXPrioritizedStermFinalizerEntry(llvm::Function *StermFinalizer, 1161fe6060f1SDimitry Andric int Priority) { 1162fe6060f1SDimitry Andric OrderGlobalInitsOrStermFinalizers Key(Priority, 1163fe6060f1SDimitry Andric PrioritizedCXXStermFinalizers.size()); 1164fe6060f1SDimitry Andric PrioritizedCXXStermFinalizers.push_back( 1165fe6060f1SDimitry Andric std::make_pair(Key, StermFinalizer)); 1166fe6060f1SDimitry Andric } 1167fe6060f1SDimitry Andric 11680b57cec5SDimitry Andric /// Create or return a runtime function declaration with the specified type 1169480093f4SDimitry Andric /// and name. If \p AssumeConvergent is true, the call will have the 1170480093f4SDimitry Andric /// convergent attribute added. 11710b57cec5SDimitry Andric llvm::FunctionCallee 11720b57cec5SDimitry Andric CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, 11730b57cec5SDimitry Andric llvm::AttributeList ExtraAttrs = llvm::AttributeList(), 1174480093f4SDimitry Andric bool Local = false, bool AssumeConvergent = false); 1175480093f4SDimitry Andric 11760b57cec5SDimitry Andric /// Create a new runtime global variable with the specified type and name. 11770b57cec5SDimitry Andric llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty, 11780b57cec5SDimitry Andric StringRef Name); 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric ///@name Custom Blocks Runtime Interfaces 11810b57cec5SDimitry Andric ///@{ 11820b57cec5SDimitry Andric 11830b57cec5SDimitry Andric llvm::Constant *getNSConcreteGlobalBlock(); 11840b57cec5SDimitry Andric llvm::Constant *getNSConcreteStackBlock(); 11850b57cec5SDimitry Andric llvm::FunctionCallee getBlockObjectAssign(); 11860b57cec5SDimitry Andric llvm::FunctionCallee getBlockObjectDispose(); 11870b57cec5SDimitry Andric 11880b57cec5SDimitry Andric ///@} 11890b57cec5SDimitry Andric 11900b57cec5SDimitry Andric llvm::Function *getLLVMLifetimeStartFn(); 11910b57cec5SDimitry Andric llvm::Function *getLLVMLifetimeEndFn(); 11920b57cec5SDimitry Andric 11930b57cec5SDimitry Andric // Make sure that this type is translated. 11940b57cec5SDimitry Andric void UpdateCompletedType(const TagDecl *TD); 11950b57cec5SDimitry Andric 11960b57cec5SDimitry Andric llvm::Constant *getMemberPointerConstant(const UnaryOperator *e); 11970b57cec5SDimitry Andric 11980b57cec5SDimitry Andric /// Emit type info if type of an expression is a variably modified 11990b57cec5SDimitry Andric /// type. Also emit proper debug info for cast types. 12000b57cec5SDimitry Andric void EmitExplicitCastExprType(const ExplicitCastExpr *E, 12010b57cec5SDimitry Andric CodeGenFunction *CGF = nullptr); 12020b57cec5SDimitry Andric 12030b57cec5SDimitry Andric /// Return the result of value-initializing the given type, i.e. a null 12040b57cec5SDimitry Andric /// expression of the given type. This is usually, but not always, an LLVM 12050b57cec5SDimitry Andric /// null constant. 12060b57cec5SDimitry Andric llvm::Constant *EmitNullConstant(QualType T); 12070b57cec5SDimitry Andric 12080b57cec5SDimitry Andric /// Return a null constant appropriate for zero-initializing a base class with 12090b57cec5SDimitry Andric /// the given type. This is usually, but not always, an LLVM null constant. 12100b57cec5SDimitry Andric llvm::Constant *EmitNullConstantForBase(const CXXRecordDecl *Record); 12110b57cec5SDimitry Andric 12120b57cec5SDimitry Andric /// Emit a general error that something can't be done. 12130b57cec5SDimitry Andric void Error(SourceLocation loc, StringRef error); 12140b57cec5SDimitry Andric 12150b57cec5SDimitry Andric /// Print out an error that codegen doesn't support the specified stmt yet. 12160b57cec5SDimitry Andric void ErrorUnsupported(const Stmt *S, const char *Type); 12170b57cec5SDimitry Andric 12180b57cec5SDimitry Andric /// Print out an error that codegen doesn't support the specified decl yet. 12190b57cec5SDimitry Andric void ErrorUnsupported(const Decl *D, const char *Type); 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric /// Set the attributes on the LLVM function for the given decl and function 12220b57cec5SDimitry Andric /// info. This applies attributes necessary for handling the ABI as well as 12230b57cec5SDimitry Andric /// user specified attributes like section. 12240b57cec5SDimitry Andric void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F, 12250b57cec5SDimitry Andric const CGFunctionInfo &FI); 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric /// Set the LLVM function attributes (sext, zext, etc). 12280b57cec5SDimitry Andric void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, 1229fe6060f1SDimitry Andric llvm::Function *F, bool IsThunk); 12300b57cec5SDimitry Andric 12310b57cec5SDimitry Andric /// Set the LLVM function attributes which only apply to a function 12320b57cec5SDimitry Andric /// definition. 12330b57cec5SDimitry Andric void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F); 12340b57cec5SDimitry Andric 1235e8d8bef9SDimitry Andric /// Set the LLVM function attributes that represent floating point 1236e8d8bef9SDimitry Andric /// environment. 1237e8d8bef9SDimitry Andric void setLLVMFunctionFEnvAttributes(const FunctionDecl *D, llvm::Function *F); 1238e8d8bef9SDimitry Andric 12390b57cec5SDimitry Andric /// Return true iff the given type uses 'sret' when used as a return type. 12400b57cec5SDimitry Andric bool ReturnTypeUsesSRet(const CGFunctionInfo &FI); 12410b57cec5SDimitry Andric 1242*fe72d8ecSDimitry Andric /// Return true iff the given type has `inreg` set. 1243*fe72d8ecSDimitry Andric bool ReturnTypeHasInReg(const CGFunctionInfo &FI); 1244*fe72d8ecSDimitry Andric 12450b57cec5SDimitry Andric /// Return true iff the given type uses an argument slot when 'sret' is used 12460b57cec5SDimitry Andric /// as a return type. 12470b57cec5SDimitry Andric bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI); 12480b57cec5SDimitry Andric 12490b57cec5SDimitry Andric /// Return true iff the given type uses 'fpret' when used as a return type. 12500b57cec5SDimitry Andric bool ReturnTypeUsesFPRet(QualType ResultType); 12510b57cec5SDimitry Andric 12520b57cec5SDimitry Andric /// Return true iff the given type uses 'fp2ret' when used as a return type. 12530b57cec5SDimitry Andric bool ReturnTypeUsesFP2Ret(QualType ResultType); 12540b57cec5SDimitry Andric 12550b57cec5SDimitry Andric /// Get the LLVM attributes and calling convention to use for a particular 12560b57cec5SDimitry Andric /// function type. 12570b57cec5SDimitry Andric /// 12580b57cec5SDimitry Andric /// \param Name - The function name. 12590b57cec5SDimitry Andric /// \param Info - The function type information. 12600b57cec5SDimitry Andric /// \param CalleeInfo - The callee information these attributes are being 12610b57cec5SDimitry Andric /// constructed for. If valid, the attributes applied to this decl may 12620b57cec5SDimitry Andric /// contribute to the function attributes and calling convention. 12630b57cec5SDimitry Andric /// \param Attrs [out] - On return, the attribute list to use. 12640b57cec5SDimitry Andric /// \param CallingConv [out] - On return, the LLVM calling convention to use. 12650b57cec5SDimitry Andric void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info, 12660b57cec5SDimitry Andric CGCalleeInfo CalleeInfo, 12670b57cec5SDimitry Andric llvm::AttributeList &Attrs, unsigned &CallingConv, 1268fe6060f1SDimitry Andric bool AttrOnCallSite, bool IsThunk); 12690b57cec5SDimitry Andric 1270c9157d92SDimitry Andric /// Adjust Memory attribute to ensure that the BE gets the right attribute 1271c9157d92SDimitry Andric // in order to generate the library call or the intrinsic for the function 1272c9157d92SDimitry Andric // name 'Name'. 1273c9157d92SDimitry Andric void AdjustMemoryAttribute(StringRef Name, CGCalleeInfo CalleeInfo, 1274c9157d92SDimitry Andric llvm::AttributeList &Attrs); 12755ffd83dbSDimitry Andric 12765ffd83dbSDimitry Andric /// Like the overload taking a `Function &`, but intended specifically 12775ffd83dbSDimitry Andric /// for frontends that want to build on Clang's target-configuration logic. 12785ffd83dbSDimitry Andric void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs); 12790b57cec5SDimitry Andric 12800b57cec5SDimitry Andric StringRef getMangledName(GlobalDecl GD); 12810b57cec5SDimitry Andric StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD); 128281ad6265SDimitry Andric const GlobalDecl getMangledNameDecl(StringRef); 12830b57cec5SDimitry Andric 12840b57cec5SDimitry Andric void EmitTentativeDefinition(const VarDecl *D); 12850b57cec5SDimitry Andric 1286480093f4SDimitry Andric void EmitExternalDeclaration(const VarDecl *D); 1287480093f4SDimitry Andric 12880b57cec5SDimitry Andric void EmitVTable(CXXRecordDecl *Class); 12890b57cec5SDimitry Andric 12900b57cec5SDimitry Andric void RefreshTypeCacheForClass(const CXXRecordDecl *Class); 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andric /// Appends Opts to the "llvm.linker.options" metadata value. 12930b57cec5SDimitry Andric void AppendLinkerOptions(StringRef Opts); 12940b57cec5SDimitry Andric 12950b57cec5SDimitry Andric /// Appends a detect mismatch command to the linker options. 12960b57cec5SDimitry Andric void AddDetectMismatch(StringRef Name, StringRef Value); 12970b57cec5SDimitry Andric 12980b57cec5SDimitry Andric /// Appends a dependent lib to the appropriate metadata value. 12990b57cec5SDimitry Andric void AddDependentLib(StringRef Lib); 13000b57cec5SDimitry Andric 13010b57cec5SDimitry Andric 13020b57cec5SDimitry Andric llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD); 13030b57cec5SDimitry Andric setFunctionLinkage(GlobalDecl GD,llvm::Function * F)13040b57cec5SDimitry Andric void setFunctionLinkage(GlobalDecl GD, llvm::Function *F) { 13050b57cec5SDimitry Andric F->setLinkage(getFunctionLinkage(GD)); 13060b57cec5SDimitry Andric } 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andric /// Return the appropriate linkage for the vtable, VTT, and type information 13090b57cec5SDimitry Andric /// of the given class. 13100b57cec5SDimitry Andric llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD); 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric /// Return the store size, in character units, of the given LLVM type. 13130b57cec5SDimitry Andric CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const; 13140b57cec5SDimitry Andric 13150b57cec5SDimitry Andric /// Returns LLVM linkage for a declarator. 13160b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes 1317271697daSDimitry Andric getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage); 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andric /// Returns LLVM linkage for a declarator. 13200b57cec5SDimitry Andric llvm::GlobalValue::LinkageTypes 1321271697daSDimitry Andric getLLVMLinkageVarDefinition(const VarDecl *VD); 13220b57cec5SDimitry Andric 13230b57cec5SDimitry Andric /// Emit all the global annotations. 13240b57cec5SDimitry Andric void EmitGlobalAnnotations(); 13250b57cec5SDimitry Andric 13260b57cec5SDimitry Andric /// Emit an annotation string. 13270b57cec5SDimitry Andric llvm::Constant *EmitAnnotationString(StringRef Str); 13280b57cec5SDimitry Andric 13290b57cec5SDimitry Andric /// Emit the annotation's translation unit. 13300b57cec5SDimitry Andric llvm::Constant *EmitAnnotationUnit(SourceLocation Loc); 13310b57cec5SDimitry Andric 13320b57cec5SDimitry Andric /// Emit the annotation line number. 13330b57cec5SDimitry Andric llvm::Constant *EmitAnnotationLineNo(SourceLocation L); 13340b57cec5SDimitry Andric 1335e8d8bef9SDimitry Andric /// Emit additional args of the annotation. 1336e8d8bef9SDimitry Andric llvm::Constant *EmitAnnotationArgs(const AnnotateAttr *Attr); 1337e8d8bef9SDimitry Andric 13380b57cec5SDimitry Andric /// Generate the llvm::ConstantStruct which contains the annotation 13390b57cec5SDimitry Andric /// information for a given GlobalValue. The annotation struct is 13400b57cec5SDimitry Andric /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the 13410b57cec5SDimitry Andric /// GlobalValue being annotated. The second field is the constant string 13420b57cec5SDimitry Andric /// created from the AnnotateAttr's annotation. The third field is a constant 13430b57cec5SDimitry Andric /// string containing the name of the translation unit. The fourth field is 13440b57cec5SDimitry Andric /// the line number in the file of the annotated value declaration. 13450b57cec5SDimitry Andric llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV, 13460b57cec5SDimitry Andric const AnnotateAttr *AA, 13470b57cec5SDimitry Andric SourceLocation L); 13480b57cec5SDimitry Andric 13490b57cec5SDimitry Andric /// Add global annotations that are set on D, for the global GV. Those 13500b57cec5SDimitry Andric /// annotations are emitted during finalization of the LLVM code. 13510b57cec5SDimitry Andric void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); 13520b57cec5SDimitry Andric 1353fe6060f1SDimitry Andric bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn, 13540b57cec5SDimitry Andric SourceLocation Loc) const; 13550b57cec5SDimitry Andric 135681ad6265SDimitry Andric bool isInNoSanitizeList(SanitizerMask Kind, llvm::GlobalVariable *GV, 135781ad6265SDimitry Andric SourceLocation Loc, QualType Ty, 135881ad6265SDimitry Andric StringRef Category = StringRef()) const; 13590b57cec5SDimitry Andric 13600b57cec5SDimitry Andric /// Imbue XRay attributes to a function, applying the always/never attribute 13610b57cec5SDimitry Andric /// lists in the process. Returns true if we did imbue attributes this way, 13620b57cec5SDimitry Andric /// false otherwise. 13630b57cec5SDimitry Andric bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc, 13640b57cec5SDimitry Andric StringRef Category = StringRef()) const; 13650b57cec5SDimitry Andric 1366fcaf7f86SDimitry Andric /// \returns true if \p Fn at \p Loc should be excluded from profile 1367fcaf7f86SDimitry Andric /// instrumentation by the SCL passed by \p -fprofile-list. 1368bdd1243dSDimitry Andric ProfileList::ExclusionType 1369bdd1243dSDimitry Andric isFunctionBlockedByProfileList(llvm::Function *Fn, SourceLocation Loc) const; 1370fcaf7f86SDimitry Andric 1371fcaf7f86SDimitry Andric /// \returns true if \p Fn at \p Loc should be excluded from profile 1372fcaf7f86SDimitry Andric /// instrumentation. 1373bdd1243dSDimitry Andric ProfileList::ExclusionType 1374bdd1243dSDimitry Andric isFunctionBlockedFromProfileInstr(llvm::Function *Fn, 1375fcaf7f86SDimitry Andric SourceLocation Loc) const; 1376e8d8bef9SDimitry Andric getSanitizerMetadata()13770b57cec5SDimitry Andric SanitizerMetadata *getSanitizerMetadata() { 13780b57cec5SDimitry Andric return SanitizerMD.get(); 13790b57cec5SDimitry Andric } 13800b57cec5SDimitry Andric addDeferredVTable(const CXXRecordDecl * RD)13810b57cec5SDimitry Andric void addDeferredVTable(const CXXRecordDecl *RD) { 13820b57cec5SDimitry Andric DeferredVTables.push_back(RD); 13830b57cec5SDimitry Andric } 13840b57cec5SDimitry Andric 13850b57cec5SDimitry Andric /// Emit code for a single global function or var decl. Forward declarations 13860b57cec5SDimitry Andric /// are emitted lazily. 13870b57cec5SDimitry Andric void EmitGlobal(GlobalDecl D); 13880b57cec5SDimitry Andric 13890b57cec5SDimitry Andric bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D); 13900b57cec5SDimitry Andric 13910b57cec5SDimitry Andric llvm::GlobalValue *GetGlobalValue(StringRef Ref); 13920b57cec5SDimitry Andric 13930b57cec5SDimitry Andric /// Set attributes which are common to any form of a global definition (alias, 13940b57cec5SDimitry Andric /// Objective-C method, function, global variable). 13950b57cec5SDimitry Andric /// 13960b57cec5SDimitry Andric /// NOTE: This should only be called for definitions. 13970b57cec5SDimitry Andric void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV); 13980b57cec5SDimitry Andric 13990b57cec5SDimitry Andric void addReplacement(StringRef Name, llvm::Constant *C); 14000b57cec5SDimitry Andric 14010b57cec5SDimitry Andric void addGlobalValReplacement(llvm::GlobalValue *GV, llvm::Constant *C); 14020b57cec5SDimitry Andric 14030b57cec5SDimitry Andric /// Emit a code for threadprivate directive. 14040b57cec5SDimitry Andric /// \param D Threadprivate declaration. 14050b57cec5SDimitry Andric void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D); 14060b57cec5SDimitry Andric 14070b57cec5SDimitry Andric /// Emit a code for declare reduction construct. 14080b57cec5SDimitry Andric void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D, 14090b57cec5SDimitry Andric CodeGenFunction *CGF = nullptr); 14100b57cec5SDimitry Andric 14110b57cec5SDimitry Andric /// Emit a code for declare mapper construct. 14120b57cec5SDimitry Andric void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D, 14130b57cec5SDimitry Andric CodeGenFunction *CGF = nullptr); 14140b57cec5SDimitry Andric 14150b57cec5SDimitry Andric /// Emit a code for requires directive. 14160b57cec5SDimitry Andric /// \param D Requires declaration 14170b57cec5SDimitry Andric void EmitOMPRequiresDecl(const OMPRequiresDecl *D); 14180b57cec5SDimitry Andric 1419fe6060f1SDimitry Andric /// Emit a code for the allocate directive. 1420fe6060f1SDimitry Andric /// \param D The allocate declaration 1421fe6060f1SDimitry Andric void EmitOMPAllocateDecl(const OMPAllocateDecl *D); 1422fe6060f1SDimitry Andric 142381ad6265SDimitry Andric /// Return the alignment specified in an allocate directive, if present. 1424bdd1243dSDimitry Andric std::optional<CharUnits> getOMPAllocateAlignment(const VarDecl *VD); 142581ad6265SDimitry Andric 14260b57cec5SDimitry Andric /// Returns whether the given record has hidden LTO visibility and therefore 14270b57cec5SDimitry Andric /// may participate in (single-module) CFI and whole-program vtable 14280b57cec5SDimitry Andric /// optimization. 14290b57cec5SDimitry Andric bool HasHiddenLTOVisibility(const CXXRecordDecl *RD); 14300b57cec5SDimitry Andric 143181ad6265SDimitry Andric /// Returns whether the given record has public LTO visibility (regardless of 143281ad6265SDimitry Andric /// -lto-whole-program-visibility) and therefore may not participate in 143381ad6265SDimitry Andric /// (single-module) CFI and whole-program vtable optimization. 143481ad6265SDimitry Andric bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD); 14355ffd83dbSDimitry Andric 1436a7dea167SDimitry Andric /// Returns the vcall visibility of the given type. This is the scope in which 1437a7dea167SDimitry Andric /// a virtual function call could be made which ends up being dispatched to a 1438a7dea167SDimitry Andric /// member function of this class. This scope can be wider than the visibility 1439a7dea167SDimitry Andric /// of the class itself when the class has a more-visible dynamic base class. 1440e8d8bef9SDimitry Andric /// The client should pass in an empty Visited set, which is used to prevent 1441e8d8bef9SDimitry Andric /// redundant recursive processing. 1442a7dea167SDimitry Andric llvm::GlobalObject::VCallVisibility 1443e8d8bef9SDimitry Andric GetVCallVisibilityLevel(const CXXRecordDecl *RD, 1444e8d8bef9SDimitry Andric llvm::DenseSet<const CXXRecordDecl *> &Visited); 1445a7dea167SDimitry Andric 14460b57cec5SDimitry Andric /// Emit type metadata for the given vtable using the given layout. 1447a7dea167SDimitry Andric void EmitVTableTypeMetadata(const CXXRecordDecl *RD, 1448a7dea167SDimitry Andric llvm::GlobalVariable *VTable, 14490b57cec5SDimitry Andric const VTableLayout &VTLayout); 14500b57cec5SDimitry Andric 1451bdd1243dSDimitry Andric llvm::Type *getVTableComponentType() const; 1452bdd1243dSDimitry Andric 14530b57cec5SDimitry Andric /// Generate a cross-DSO type identifier for MD. 14540b57cec5SDimitry Andric llvm::ConstantInt *CreateCrossDsoCfiTypeId(llvm::Metadata *MD); 14550b57cec5SDimitry Andric 1456bdd1243dSDimitry Andric /// Generate a KCFI type identifier for T. 1457bdd1243dSDimitry Andric llvm::ConstantInt *CreateKCFITypeId(QualType T); 1458bdd1243dSDimitry Andric 14590b57cec5SDimitry Andric /// Create a metadata identifier for the given type. This may either be an 14600b57cec5SDimitry Andric /// MDString (for external identifiers) or a distinct unnamed MDNode (for 14610b57cec5SDimitry Andric /// internal identifiers). 14620b57cec5SDimitry Andric llvm::Metadata *CreateMetadataIdentifierForType(QualType T); 14630b57cec5SDimitry Andric 14640b57cec5SDimitry Andric /// Create a metadata identifier that is intended to be used to check virtual 14650b57cec5SDimitry Andric /// calls via a member function pointer. 14660b57cec5SDimitry Andric llvm::Metadata *CreateMetadataIdentifierForVirtualMemPtrType(QualType T); 14670b57cec5SDimitry Andric 14680b57cec5SDimitry Andric /// Create a metadata identifier for the generalization of the given type. 14690b57cec5SDimitry Andric /// This may either be an MDString (for external identifiers) or a distinct 14700b57cec5SDimitry Andric /// unnamed MDNode (for internal identifiers). 14710b57cec5SDimitry Andric llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T); 14720b57cec5SDimitry Andric 14730b57cec5SDimitry Andric /// Create and attach type metadata to the given function. 14740b57cec5SDimitry Andric void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD, 14750b57cec5SDimitry Andric llvm::Function *F); 14760b57cec5SDimitry Andric 1477bdd1243dSDimitry Andric /// Set type metadata to the given function. 1478bdd1243dSDimitry Andric void setKCFIType(const FunctionDecl *FD, llvm::Function *F); 1479bdd1243dSDimitry Andric 1480bdd1243dSDimitry Andric /// Emit KCFI type identifier constants and remove unused identifiers. 1481bdd1243dSDimitry Andric void finalizeKCFITypes(); 1482bdd1243dSDimitry Andric 1483fe6060f1SDimitry Andric /// Whether this function's return type has no side effects, and thus may 1484fe6060f1SDimitry Andric /// be trivially discarded if it is unused. 1485bdd1243dSDimitry Andric bool MayDropFunctionReturn(const ASTContext &Context, 1486bdd1243dSDimitry Andric QualType ReturnType) const; 1487fe6060f1SDimitry Andric 14880b57cec5SDimitry Andric /// Returns whether this module needs the "all-vtables" type identifier. 14890b57cec5SDimitry Andric bool NeedAllVtablesTypeId() const; 14900b57cec5SDimitry Andric 14910b57cec5SDimitry Andric /// Create and attach type metadata for the given vtable. 14920b57cec5SDimitry Andric void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset, 14930b57cec5SDimitry Andric const CXXRecordDecl *RD); 14940b57cec5SDimitry Andric 14950b57cec5SDimitry Andric /// Return a vector of most-base classes for RD. This is used to implement 14960b57cec5SDimitry Andric /// control flow integrity checks for member function pointers. 14970b57cec5SDimitry Andric /// 14980b57cec5SDimitry Andric /// A most-base class of a class C is defined as a recursive base class of C, 14990b57cec5SDimitry Andric /// including C itself, that does not have any bases. 1500c9157d92SDimitry Andric SmallVector<const CXXRecordDecl *, 0> 15010b57cec5SDimitry Andric getMostBaseClasses(const CXXRecordDecl *RD); 15020b57cec5SDimitry Andric 15030b57cec5SDimitry Andric /// Get the declaration of std::terminate for the platform. 15040b57cec5SDimitry Andric llvm::FunctionCallee getTerminateFn(); 15050b57cec5SDimitry Andric 15060b57cec5SDimitry Andric llvm::SanitizerStatReport &getSanStats(); 15070b57cec5SDimitry Andric 15080b57cec5SDimitry Andric llvm::Value * 15090b57cec5SDimitry Andric createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF); 15100b57cec5SDimitry Andric 15110b57cec5SDimitry Andric /// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument 15120b57cec5SDimitry Andric /// information in the program executable. The argument information stored 15130b57cec5SDimitry Andric /// includes the argument name, its type, the address and access qualifiers 15140b57cec5SDimitry Andric /// used. This helper can be used to generate metadata for source code kernel 15150b57cec5SDimitry Andric /// function as well as generated implicitly kernels. If a kernel is generated 15160b57cec5SDimitry Andric /// implicitly null value has to be passed to the last two parameters, 15170b57cec5SDimitry Andric /// otherwise all parameters must have valid non-null values. 15180b57cec5SDimitry Andric /// \param FN is a pointer to IR function being generated. 15190b57cec5SDimitry Andric /// \param FD is a pointer to function declaration if any. 15200b57cec5SDimitry Andric /// \param CGF is a pointer to CodeGenFunction that generates this function. 152181ad6265SDimitry Andric void GenKernelArgMetadata(llvm::Function *FN, 15220b57cec5SDimitry Andric const FunctionDecl *FD = nullptr, 15230b57cec5SDimitry Andric CodeGenFunction *CGF = nullptr); 15240b57cec5SDimitry Andric 15250b57cec5SDimitry Andric /// Get target specific null pointer. 15260b57cec5SDimitry Andric /// \param T is the LLVM type of the null pointer. 15270b57cec5SDimitry Andric /// \param QT is the clang QualType of the null pointer. 15280b57cec5SDimitry Andric llvm::Constant *getNullPointer(llvm::PointerType *T, QualType QT); 15290b57cec5SDimitry Andric 15305ffd83dbSDimitry Andric CharUnits getNaturalTypeAlignment(QualType T, 15315ffd83dbSDimitry Andric LValueBaseInfo *BaseInfo = nullptr, 15325ffd83dbSDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr, 15335ffd83dbSDimitry Andric bool forPointeeType = false); 15345ffd83dbSDimitry Andric CharUnits getNaturalPointeeTypeAlignment(QualType T, 15355ffd83dbSDimitry Andric LValueBaseInfo *BaseInfo = nullptr, 15365ffd83dbSDimitry Andric TBAAAccessInfo *TBAAInfo = nullptr); 15375ffd83dbSDimitry Andric bool stopAutoInit(); 15385ffd83dbSDimitry Andric 15392a66634dSDimitry Andric /// Print the postfix for externalized static variable or kernels for single 154081ad6265SDimitry Andric /// source offloading languages CUDA and HIP. The unique postfix is created 154181ad6265SDimitry Andric /// using either the CUID argument, or the file's UniqueID and active macros. 154281ad6265SDimitry Andric /// The fallback method without a CUID requires that the offloading toolchain 154381ad6265SDimitry Andric /// does not define separate macros via the -cc1 options. 15442a66634dSDimitry Andric void printPostfixForExternalizedDecl(llvm::raw_ostream &OS, 15452a66634dSDimitry Andric const Decl *D) const; 1546fe6060f1SDimitry Andric 154781ad6265SDimitry Andric /// Move some lazily-emitted states to the NewBuilder. This is especially 154881ad6265SDimitry Andric /// essential for the incremental parsing environment like Clang Interpreter, 154981ad6265SDimitry Andric /// because we'll lose all important information after each repl. 1550fcaf7f86SDimitry Andric void moveLazyEmissionStates(CodeGenModule *NewBuilder); 155181ad6265SDimitry Andric 1552c9157d92SDimitry Andric /// Emit the IR encoding to attach the CUDA launch bounds attribute to \p F. 1553c9157d92SDimitry Andric /// If \p MaxThreadsVal is not nullptr, the max threads value is stored in it, 1554c9157d92SDimitry Andric /// if a valid one was found. 1555c9157d92SDimitry Andric void handleCUDALaunchBoundsAttr(llvm::Function *F, 1556c9157d92SDimitry Andric const CUDALaunchBoundsAttr *A, 1557c9157d92SDimitry Andric int32_t *MaxThreadsVal = nullptr, 1558c9157d92SDimitry Andric int32_t *MinBlocksVal = nullptr, 1559c9157d92SDimitry Andric int32_t *MaxClusterRankVal = nullptr); 1560c9157d92SDimitry Andric 1561c9157d92SDimitry Andric /// Emit the IR encoding to attach the AMD GPU flat-work-group-size attribute 1562c9157d92SDimitry Andric /// to \p F. Alternatively, the work group size can be taken from a \p 1563c9157d92SDimitry Andric /// ReqdWGS. If \p MinThreadsVal is not nullptr, the min threads value is 1564c9157d92SDimitry Andric /// stored in it, if a valid one was found. If \p MaxThreadsVal is not 1565c9157d92SDimitry Andric /// nullptr, the max threads value is stored in it, if a valid one was found. 1566c9157d92SDimitry Andric void handleAMDGPUFlatWorkGroupSizeAttr( 1567c9157d92SDimitry Andric llvm::Function *F, const AMDGPUFlatWorkGroupSizeAttr *A, 1568c9157d92SDimitry Andric const ReqdWorkGroupSizeAttr *ReqdWGS = nullptr, 1569c9157d92SDimitry Andric int32_t *MinThreadsVal = nullptr, int32_t *MaxThreadsVal = nullptr); 1570c9157d92SDimitry Andric 1571c9157d92SDimitry Andric /// Emit the IR encoding to attach the AMD GPU waves-per-eu attribute to \p F. 1572c9157d92SDimitry Andric void handleAMDGPUWavesPerEUAttr(llvm::Function *F, 1573c9157d92SDimitry Andric const AMDGPUWavesPerEUAttr *A); 1574c9157d92SDimitry Andric 1575c9157d92SDimitry Andric llvm::Constant * 1576c9157d92SDimitry Andric GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, LangAS AddrSpace, 1577c9157d92SDimitry Andric const VarDecl *D, 1578c9157d92SDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition); 1579c9157d92SDimitry Andric 1580c9157d92SDimitry Andric // FIXME: Hardcoding priority here is gross. 1581c9157d92SDimitry Andric void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535, 1582c9157d92SDimitry Andric unsigned LexOrder = ~0U, 1583c9157d92SDimitry Andric llvm::Constant *AssociatedData = nullptr); 1584c9157d92SDimitry Andric void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535, 1585c9157d92SDimitry Andric bool IsDtorAttrFunc = false); 1586c9157d92SDimitry Andric 15870b57cec5SDimitry Andric private: 15880b57cec5SDimitry Andric llvm::Constant *GetOrCreateLLVMFunction( 15890b57cec5SDimitry Andric StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable, 15900b57cec5SDimitry Andric bool DontDefer = false, bool IsThunk = false, 15910b57cec5SDimitry Andric llvm::AttributeList ExtraAttrs = llvm::AttributeList(), 15920b57cec5SDimitry Andric ForDefinition_t IsForDefinition = NotForDefinition); 15930b57cec5SDimitry Andric 159481ad6265SDimitry Andric // References to multiversion functions are resolved through an implicitly 159581ad6265SDimitry Andric // defined resolver function. This function is responsible for creating 159681ad6265SDimitry Andric // the resolver symbol for the provided declaration. The value returned 159781ad6265SDimitry Andric // will be for an ifunc (llvm::GlobalIFunc) if the current target supports 159881ad6265SDimitry Andric // that feature and for a regular function (llvm::GlobalValue) otherwise. 159981ad6265SDimitry Andric llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD); 160081ad6265SDimitry Andric 160181ad6265SDimitry Andric // In scenarios where a function is not known to be a multiversion function 160281ad6265SDimitry Andric // until a later declaration, it is sometimes necessary to change the 160381ad6265SDimitry Andric // previously created mangled name to align with requirements of whatever 160481ad6265SDimitry Andric // multiversion function kind the function is now known to be. This function 160581ad6265SDimitry Andric // is responsible for performing such mangled name updates. 160604eeddc0SDimitry Andric void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD, 160704eeddc0SDimitry Andric StringRef &CurName); 16080b57cec5SDimitry Andric 16090b57cec5SDimitry Andric bool GetCPUAndFeaturesAttributes(GlobalDecl GD, 1610fe013be4SDimitry Andric llvm::AttrBuilder &AttrBuilder, 1611fe013be4SDimitry Andric bool SetTargetFeatures = true); 16120b57cec5SDimitry Andric void setNonAliasAttributes(GlobalDecl GD, llvm::GlobalObject *GO); 16130b57cec5SDimitry Andric 16140b57cec5SDimitry Andric /// Set function attributes for a function declaration. 16150b57cec5SDimitry Andric void SetFunctionAttributes(GlobalDecl GD, llvm::Function *F, 16160b57cec5SDimitry Andric bool IsIncompleteFunction, bool IsThunk); 16170b57cec5SDimitry Andric 16180b57cec5SDimitry Andric void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr); 16190b57cec5SDimitry Andric 16200b57cec5SDimitry Andric void EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV); 16210b57cec5SDimitry Andric void EmitMultiVersionFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV); 16220b57cec5SDimitry Andric 16230b57cec5SDimitry Andric void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false); 1624480093f4SDimitry Andric void EmitExternalVarDeclaration(const VarDecl *D); 16250b57cec5SDimitry Andric void EmitAliasDefinition(GlobalDecl GD); 16260b57cec5SDimitry Andric void emitIFuncDefinition(GlobalDecl GD); 16270b57cec5SDimitry Andric void emitCPUDispatchDefinition(GlobalDecl GD); 16280b57cec5SDimitry Andric void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D); 16290b57cec5SDimitry Andric void EmitObjCIvarInitializations(ObjCImplementationDecl *D); 16300b57cec5SDimitry Andric 16310b57cec5SDimitry Andric // C++ related functions. 16320b57cec5SDimitry Andric 16330b57cec5SDimitry Andric void EmitDeclContext(const DeclContext *DC); 16340b57cec5SDimitry Andric void EmitLinkageSpec(const LinkageSpecDecl *D); 1635bdd1243dSDimitry Andric void EmitTopLevelStmt(const TopLevelStmtDecl *D); 16360b57cec5SDimitry Andric 16370b57cec5SDimitry Andric /// Emit the function that initializes C++ thread_local variables. 16380b57cec5SDimitry Andric void EmitCXXThreadLocalInitFunc(); 16390b57cec5SDimitry Andric 1640fcaf7f86SDimitry Andric /// Emit the function that initializes global variables for a C++ Module. 1641fcaf7f86SDimitry Andric void EmitCXXModuleInitFunc(clang::Module *Primary); 1642fcaf7f86SDimitry Andric 16430b57cec5SDimitry Andric /// Emit the function that initializes C++ globals. 16440b57cec5SDimitry Andric void EmitCXXGlobalInitFunc(); 16450b57cec5SDimitry Andric 16465ffd83dbSDimitry Andric /// Emit the function that performs cleanup associated with C++ globals. 16475ffd83dbSDimitry Andric void EmitCXXGlobalCleanUpFunc(); 16480b57cec5SDimitry Andric 16490b57cec5SDimitry Andric /// Emit the function that initializes the specified global (if PerformInit is 16500b57cec5SDimitry Andric /// true) and registers its destructor. 16510b57cec5SDimitry Andric void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D, 16520b57cec5SDimitry Andric llvm::GlobalVariable *Addr, 16530b57cec5SDimitry Andric bool PerformInit); 16540b57cec5SDimitry Andric 16550b57cec5SDimitry Andric void EmitPointerToInitFunc(const VarDecl *VD, llvm::GlobalVariable *Addr, 16560b57cec5SDimitry Andric llvm::Function *InitFunc, InitSegAttr *ISA); 16570b57cec5SDimitry Andric 16580b57cec5SDimitry Andric /// EmitCtorList - Generates a global array of functions and priorities using 16590b57cec5SDimitry Andric /// the given list and name. This array will have appending linkage and is 16600b57cec5SDimitry Andric /// suitable for use as a LLVM constructor or destructor array. Clears Fns. 16610b57cec5SDimitry Andric void EmitCtorList(CtorList &Fns, const char *GlobalName); 16620b57cec5SDimitry Andric 16630b57cec5SDimitry Andric /// Emit any needed decls for which code generation was deferred. 16640b57cec5SDimitry Andric void EmitDeferred(); 16650b57cec5SDimitry Andric 16660b57cec5SDimitry Andric /// Try to emit external vtables as available_externally if they have emitted 16670b57cec5SDimitry Andric /// all inlined virtual functions. It runs after EmitDeferred() and therefore 16680b57cec5SDimitry Andric /// is not allowed to create new references to things that need to be emitted 16690b57cec5SDimitry Andric /// lazily. 16700b57cec5SDimitry Andric void EmitVTablesOpportunistically(); 16710b57cec5SDimitry Andric 16720b57cec5SDimitry Andric /// Call replaceAllUsesWith on all pairs in Replacements. 16730b57cec5SDimitry Andric void applyReplacements(); 16740b57cec5SDimitry Andric 16750b57cec5SDimitry Andric /// Call replaceAllUsesWith on all pairs in GlobalValReplacements. 16760b57cec5SDimitry Andric void applyGlobalValReplacements(); 16770b57cec5SDimitry Andric 16780b57cec5SDimitry Andric void checkAliases(); 16790b57cec5SDimitry Andric 16800b57cec5SDimitry Andric std::map<int, llvm::TinyPtrVector<llvm::Function *>> DtorsUsingAtExit; 16810b57cec5SDimitry Andric 16820b57cec5SDimitry Andric /// Register functions annotated with __attribute__((destructor)) using 16830b57cec5SDimitry Andric /// __cxa_atexit, if it is available, or atexit otherwise. 16840b57cec5SDimitry Andric void registerGlobalDtorsWithAtExit(); 16850b57cec5SDimitry Andric 1686e8d8bef9SDimitry Andric // When using sinit and sterm functions, unregister 1687e8d8bef9SDimitry Andric // __attribute__((destructor)) annotated functions which were previously 1688e8d8bef9SDimitry Andric // registered by the atexit subroutine using unatexit. 1689e8d8bef9SDimitry Andric void unregisterGlobalDtorsWithUnAtExit(); 1690e8d8bef9SDimitry Andric 169181ad6265SDimitry Andric /// Emit deferred multiversion function resolvers and associated variants. 16920b57cec5SDimitry Andric void emitMultiVersionFunctions(); 16930b57cec5SDimitry Andric 16940b57cec5SDimitry Andric /// Emit any vtables which we deferred and still have a use for. 16950b57cec5SDimitry Andric void EmitDeferredVTables(); 16960b57cec5SDimitry Andric 16970b57cec5SDimitry Andric /// Emit a dummy function that reference a CoreFoundation symbol when 16980b57cec5SDimitry Andric /// @available is used on Darwin. 16990b57cec5SDimitry Andric void emitAtAvailableLinkGuard(); 17000b57cec5SDimitry Andric 17010b57cec5SDimitry Andric /// Emit the llvm.used and llvm.compiler.used metadata. 17020b57cec5SDimitry Andric void emitLLVMUsed(); 17030b57cec5SDimitry Andric 1704fcaf7f86SDimitry Andric /// For C++20 Itanium ABI, emit the initializers for the module. 1705fcaf7f86SDimitry Andric void EmitModuleInitializers(clang::Module *Primary); 1706fcaf7f86SDimitry Andric 17070b57cec5SDimitry Andric /// Emit the link options introduced by imported modules. 17080b57cec5SDimitry Andric void EmitModuleLinkOptions(); 17090b57cec5SDimitry Andric 171081ad6265SDimitry Andric /// Helper function for EmitStaticExternCAliases() to redirect ifuncs that 171181ad6265SDimitry Andric /// have a resolver name that matches 'Elem' to instead resolve to the name of 171281ad6265SDimitry Andric /// 'CppFunc'. This redirection is necessary in cases where 'Elem' has a name 171381ad6265SDimitry Andric /// that will be emitted as an alias of the name bound to 'CppFunc'; ifuncs 171481ad6265SDimitry Andric /// may not reference aliases. Redirection is only performed if 'Elem' is only 171581ad6265SDimitry Andric /// used by ifuncs in which case, 'Elem' is destroyed. 'true' is returned if 171681ad6265SDimitry Andric /// redirection is successful, and 'false' is returned otherwise. 171781ad6265SDimitry Andric bool CheckAndReplaceExternCIFuncs(llvm::GlobalValue *Elem, 171881ad6265SDimitry Andric llvm::GlobalValue *CppFunc); 171981ad6265SDimitry Andric 17200b57cec5SDimitry Andric /// Emit aliases for internal-linkage declarations inside "C" language 17210b57cec5SDimitry Andric /// linkage specifications, giving them the "expected" name where possible. 17220b57cec5SDimitry Andric void EmitStaticExternCAliases(); 17230b57cec5SDimitry Andric 17240b57cec5SDimitry Andric void EmitDeclMetadata(); 17250b57cec5SDimitry Andric 17260b57cec5SDimitry Andric /// Emit the Clang version as llvm.ident metadata. 17270b57cec5SDimitry Andric void EmitVersionIdentMetadata(); 17280b57cec5SDimitry Andric 17290b57cec5SDimitry Andric /// Emit the Clang commandline as llvm.commandline metadata. 17300b57cec5SDimitry Andric void EmitCommandLineMetadata(); 17310b57cec5SDimitry Andric 17325ffd83dbSDimitry Andric /// Emit the module flag metadata used to pass options controlling the 17335ffd83dbSDimitry Andric /// the backend to LLVM. 1734fe013be4SDimitry Andric void EmitBackendOptionsMetadata(const CodeGenOptions &CodeGenOpts); 17350b57cec5SDimitry Andric 17360b57cec5SDimitry Andric /// Emits OpenCL specific Metadata e.g. OpenCL version. 17370b57cec5SDimitry Andric void EmitOpenCLMetadata(); 17380b57cec5SDimitry Andric 17390b57cec5SDimitry Andric /// Emit the llvm.gcov metadata used to tell LLVM where to emit the .gcno and 17400b57cec5SDimitry Andric /// .gcda files in a way that persists in .bc files. 17410b57cec5SDimitry Andric void EmitCoverageFile(); 17420b57cec5SDimitry Andric 17430b57cec5SDimitry Andric /// Determine whether the definition must be emitted; if this returns \c 17440b57cec5SDimitry Andric /// false, the definition can be emitted lazily if it's used. 17450b57cec5SDimitry Andric bool MustBeEmitted(const ValueDecl *D); 17460b57cec5SDimitry Andric 17470b57cec5SDimitry Andric /// Determine whether the definition can be emitted eagerly, or should be 17480b57cec5SDimitry Andric /// delayed until the end of the translation unit. This is relevant for 17490b57cec5SDimitry Andric /// definitions whose linkage can change, e.g. implicit function instantions 17500b57cec5SDimitry Andric /// which may later be explicitly instantiated. 17510b57cec5SDimitry Andric bool MayBeEmittedEagerly(const ValueDecl *D); 17520b57cec5SDimitry Andric 17530b57cec5SDimitry Andric /// Check whether we can use a "simpler", more core exceptions personality 17540b57cec5SDimitry Andric /// function. 17550b57cec5SDimitry Andric void SimplifyPersonality(); 17560b57cec5SDimitry Andric 1757fe013be4SDimitry Andric /// Helper function for getDefaultFunctionAttributes. Builds a set of function 1758fe013be4SDimitry Andric /// attributes which can be simply added to a function. 1759fe013be4SDimitry Andric void getTrivialDefaultFunctionAttributes(StringRef Name, bool HasOptnone, 1760fe013be4SDimitry Andric bool AttrOnCallSite, 1761fe013be4SDimitry Andric llvm::AttrBuilder &FuncAttrs); 1762fe013be4SDimitry Andric 17635ffd83dbSDimitry Andric /// Helper function for ConstructAttributeList and 17645ffd83dbSDimitry Andric /// addDefaultFunctionDefinitionAttributes. Builds a set of function 17655ffd83dbSDimitry Andric /// attributes to add to a function with the given properties. 17665ffd83dbSDimitry Andric void getDefaultFunctionAttributes(StringRef Name, bool HasOptnone, 17670b57cec5SDimitry Andric bool AttrOnCallSite, 17680b57cec5SDimitry Andric llvm::AttrBuilder &FuncAttrs); 17690b57cec5SDimitry Andric 17700b57cec5SDimitry Andric llvm::Metadata *CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map, 17710b57cec5SDimitry Andric StringRef Suffix); 17720b57cec5SDimitry Andric }; 17730b57cec5SDimitry Andric 17740b57cec5SDimitry Andric } // end namespace CodeGen 17750b57cec5SDimitry Andric } // end namespace clang 17760b57cec5SDimitry Andric 17770b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H 1778