1f22ef01cSRoman Divacky //===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- C++ -*-===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This is the internal per-translation-unit state used for llvm translation.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
1439d628a0SDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H
1539d628a0SDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H
16f22ef01cSRoman Divacky 
17139f7f9bSDimitry Andric #include "CGVTables.h"
180623d748SDimitry Andric #include "CodeGenTypeCache.h"
19139f7f9bSDimitry Andric #include "CodeGenTypes.h"
2039d628a0SDimitry Andric #include "SanitizerMetadata.h"
21f22ef01cSRoman Divacky #include "clang/AST/Attr.h"
22f22ef01cSRoman Divacky #include "clang/AST/DeclCXX.h"
23f22ef01cSRoman Divacky #include "clang/AST/DeclObjC.h"
24e7145dcbSDimitry Andric #include "clang/AST/DeclOpenMP.h"
2517a519f9SDimitry Andric #include "clang/AST/GlobalDecl.h"
262754fe60SDimitry Andric #include "clang/AST/Mangle.h"
27139f7f9bSDimitry Andric #include "clang/Basic/ABI.h"
28139f7f9bSDimitry Andric #include "clang/Basic/LangOptions.h"
29139f7f9bSDimitry Andric #include "clang/Basic/Module.h"
3039d628a0SDimitry Andric #include "clang/Basic/SanitizerBlacklist.h"
3120e90f04SDimitry Andric #include "clang/Basic/XRayLists.h"
32f22ef01cSRoman Divacky #include "llvm/ADT/DenseMap.h"
33139f7f9bSDimitry Andric #include "llvm/ADT/SetVector.h"
34f22ef01cSRoman Divacky #include "llvm/ADT/SmallPtrSet.h"
35139f7f9bSDimitry Andric #include "llvm/ADT/StringMap.h"
36139f7f9bSDimitry Andric #include "llvm/IR/Module.h"
3759d1ed5bSDimitry Andric #include "llvm/IR/ValueHandle.h"
38e7145dcbSDimitry Andric #include "llvm/Transforms/Utils/SanitizerStats.h"
39f22ef01cSRoman Divacky 
40f22ef01cSRoman Divacky namespace llvm {
41f22ef01cSRoman Divacky class Module;
42f22ef01cSRoman Divacky class Constant;
4317a519f9SDimitry Andric class ConstantInt;
44f22ef01cSRoman Divacky class Function;
45f22ef01cSRoman Divacky class GlobalValue;
463861d79fSDimitry Andric class DataLayout;
47f22ef01cSRoman Divacky class FunctionType;
48f22ef01cSRoman Divacky class LLVMContext;
4959d1ed5bSDimitry Andric class IndexedInstrProfReader;
50f22ef01cSRoman Divacky }
51f22ef01cSRoman Divacky 
52f22ef01cSRoman Divacky namespace clang {
53f22ef01cSRoman Divacky class ASTContext;
54139f7f9bSDimitry Andric class AtomicType;
55f22ef01cSRoman Divacky class FunctionDecl;
56f22ef01cSRoman Divacky class IdentifierInfo;
57f22ef01cSRoman Divacky class ObjCMethodDecl;
58f22ef01cSRoman Divacky class ObjCImplementationDecl;
59f22ef01cSRoman Divacky class ObjCCategoryImplDecl;
60f22ef01cSRoman Divacky class ObjCProtocolDecl;
61f22ef01cSRoman Divacky class ObjCEncodeExpr;
62f22ef01cSRoman Divacky class BlockExpr;
63f22ef01cSRoman Divacky class CharUnits;
64f22ef01cSRoman Divacky class Decl;
65f22ef01cSRoman Divacky class Expr;
66f22ef01cSRoman Divacky class Stmt;
67dff0c46cSDimitry Andric class InitListExpr;
68f22ef01cSRoman Divacky class StringLiteral;
69f22ef01cSRoman Divacky class NamedDecl;
70f22ef01cSRoman Divacky class ValueDecl;
71f22ef01cSRoman Divacky class VarDecl;
72f22ef01cSRoman Divacky class LangOptions;
73f22ef01cSRoman Divacky class CodeGenOptions;
743dac3a9bSDimitry Andric class HeaderSearchOptions;
753dac3a9bSDimitry Andric class PreprocessorOptions;
766122f3e6SDimitry Andric class DiagnosticsEngine;
77f22ef01cSRoman Divacky class AnnotateAttr;
78f22ef01cSRoman Divacky class CXXDestructorDecl;
79139f7f9bSDimitry Andric class Module;
8039d628a0SDimitry Andric class CoverageSourceInfo;
81f22ef01cSRoman Divacky 
82f22ef01cSRoman Divacky namespace CodeGen {
83f22ef01cSRoman Divacky 
843b0f4066SDimitry Andric class CallArgList;
85f22ef01cSRoman Divacky class CodeGenFunction;
862754fe60SDimitry Andric class CodeGenTBAA;
87e580952dSDimitry Andric class CGCXXABI;
88f22ef01cSRoman Divacky class CGDebugInfo;
89f22ef01cSRoman Divacky class CGObjCRuntime;
906122f3e6SDimitry Andric class CGOpenCLRuntime;
9159d1ed5bSDimitry Andric class CGOpenMPRuntime;
926122f3e6SDimitry Andric class CGCUDARuntime;
932754fe60SDimitry Andric class BlockFieldFlags;
943b0f4066SDimitry Andric class FunctionArgList;
9539d628a0SDimitry Andric class CoverageMappingModuleGen;
96e7145dcbSDimitry Andric class TargetCodeGenInfo;
97f22ef01cSRoman Divacky 
9844290647SDimitry Andric enum ForDefinition_t : bool {
9944290647SDimitry Andric   NotForDefinition = false,
10044290647SDimitry Andric   ForDefinition = true
10144290647SDimitry Andric };
10244290647SDimitry Andric 
103ffd1746dSEd Schouten struct OrderGlobalInits {
104ffd1746dSEd Schouten   unsigned int priority;
105ffd1746dSEd Schouten   unsigned int lex_order;
OrderGlobalInitsOrderGlobalInits106ffd1746dSEd Schouten   OrderGlobalInits(unsigned int p, unsigned int l)
107ffd1746dSEd Schouten       : priority(p), lex_order(l) {}
108ffd1746dSEd Schouten 
109ffd1746dSEd Schouten   bool operator==(const OrderGlobalInits &RHS) const {
11059d1ed5bSDimitry Andric     return priority == RHS.priority && lex_order == RHS.lex_order;
111ffd1746dSEd Schouten   }
112ffd1746dSEd Schouten 
113ffd1746dSEd Schouten   bool operator<(const OrderGlobalInits &RHS) const {
11459d1ed5bSDimitry Andric     return std::tie(priority, lex_order) <
11559d1ed5bSDimitry Andric            std::tie(RHS.priority, RHS.lex_order);
116ffd1746dSEd Schouten   }
117ffd1746dSEd Schouten };
118ffd1746dSEd Schouten 
1190623d748SDimitry Andric struct ObjCEntrypoints {
ObjCEntrypointsObjCEntrypoints1200623d748SDimitry Andric   ObjCEntrypoints() { memset(this, 0, sizeof(*this)); }
121bd5abe19SDimitry Andric 
122*b5893f02SDimitry Andric   /// void objc_alloc(id);
123*b5893f02SDimitry Andric   llvm::Constant *objc_alloc;
124*b5893f02SDimitry Andric 
125*b5893f02SDimitry Andric   /// void objc_allocWithZone(id);
126*b5893f02SDimitry Andric   llvm::Constant *objc_allocWithZone;
127*b5893f02SDimitry Andric 
12817a519f9SDimitry Andric   /// void objc_autoreleasePoolPop(void*);
12917a519f9SDimitry Andric   llvm::Constant *objc_autoreleasePoolPop;
13017a519f9SDimitry Andric 
131*b5893f02SDimitry Andric   /// void objc_autoreleasePoolPop(void*);
132*b5893f02SDimitry Andric   /// Note this method is used when we are using exception handling
133*b5893f02SDimitry Andric   llvm::Constant *objc_autoreleasePoolPopInvoke;
134*b5893f02SDimitry Andric 
13517a519f9SDimitry Andric   /// void *objc_autoreleasePoolPush(void);
13617a519f9SDimitry Andric   llvm::Constant *objc_autoreleasePoolPush;
13717a519f9SDimitry Andric 
13817a519f9SDimitry Andric   /// id objc_autorelease(id);
13917a519f9SDimitry Andric   llvm::Constant *objc_autorelease;
14017a519f9SDimitry Andric 
141*b5893f02SDimitry Andric   /// id objc_autorelease(id);
142*b5893f02SDimitry Andric   /// Note this is the runtime method not the intrinsic.
143*b5893f02SDimitry Andric   llvm::Constant *objc_autoreleaseRuntimeFunction;
144*b5893f02SDimitry Andric 
14517a519f9SDimitry Andric   /// id objc_autoreleaseReturnValue(id);
14617a519f9SDimitry Andric   llvm::Constant *objc_autoreleaseReturnValue;
14717a519f9SDimitry Andric 
14817a519f9SDimitry Andric   /// void objc_copyWeak(id *dest, id *src);
14917a519f9SDimitry Andric   llvm::Constant *objc_copyWeak;
15017a519f9SDimitry Andric 
15117a519f9SDimitry Andric   /// void objc_destroyWeak(id*);
15217a519f9SDimitry Andric   llvm::Constant *objc_destroyWeak;
15317a519f9SDimitry Andric 
15417a519f9SDimitry Andric   /// id objc_initWeak(id*, id);
15517a519f9SDimitry Andric   llvm::Constant *objc_initWeak;
15617a519f9SDimitry Andric 
15717a519f9SDimitry Andric   /// id objc_loadWeak(id*);
15817a519f9SDimitry Andric   llvm::Constant *objc_loadWeak;
15917a519f9SDimitry Andric 
16017a519f9SDimitry Andric   /// id objc_loadWeakRetained(id*);
16117a519f9SDimitry Andric   llvm::Constant *objc_loadWeakRetained;
16217a519f9SDimitry Andric 
16317a519f9SDimitry Andric   /// void objc_moveWeak(id *dest, id *src);
16417a519f9SDimitry Andric   llvm::Constant *objc_moveWeak;
16517a519f9SDimitry Andric 
16617a519f9SDimitry Andric   /// id objc_retain(id);
16717a519f9SDimitry Andric   llvm::Constant *objc_retain;
16817a519f9SDimitry Andric 
169*b5893f02SDimitry Andric   /// id objc_retain(id);
170*b5893f02SDimitry Andric   /// Note this is the runtime method not the intrinsic.
171*b5893f02SDimitry Andric   llvm::Constant *objc_retainRuntimeFunction;
172*b5893f02SDimitry Andric 
17317a519f9SDimitry Andric   /// id objc_retainAutorelease(id);
17417a519f9SDimitry Andric   llvm::Constant *objc_retainAutorelease;
17517a519f9SDimitry Andric 
17617a519f9SDimitry Andric   /// id objc_retainAutoreleaseReturnValue(id);
17717a519f9SDimitry Andric   llvm::Constant *objc_retainAutoreleaseReturnValue;
17817a519f9SDimitry Andric 
17917a519f9SDimitry Andric   /// id objc_retainAutoreleasedReturnValue(id);
18017a519f9SDimitry Andric   llvm::Constant *objc_retainAutoreleasedReturnValue;
18117a519f9SDimitry Andric 
18217a519f9SDimitry Andric   /// id objc_retainBlock(id);
18317a519f9SDimitry Andric   llvm::Constant *objc_retainBlock;
18417a519f9SDimitry Andric 
18517a519f9SDimitry Andric   /// void objc_release(id);
18617a519f9SDimitry Andric   llvm::Constant *objc_release;
18717a519f9SDimitry Andric 
188*b5893f02SDimitry Andric   /// void objc_release(id);
189*b5893f02SDimitry Andric   /// Note this is the runtime method not the intrinsic.
190*b5893f02SDimitry Andric   llvm::Constant *objc_releaseRuntimeFunction;
191*b5893f02SDimitry Andric 
1922bcad0d8SDimitry Andric   /// void objc_storeStrong(id*, id);
19317a519f9SDimitry Andric   llvm::Constant *objc_storeStrong;
19417a519f9SDimitry Andric 
19517a519f9SDimitry Andric   /// id objc_storeWeak(id*, id);
19617a519f9SDimitry Andric   llvm::Constant *objc_storeWeak;
19717a519f9SDimitry Andric 
198e7145dcbSDimitry Andric   /// id objc_unsafeClaimAutoreleasedReturnValue(id);
199e7145dcbSDimitry Andric   llvm::Constant *objc_unsafeClaimAutoreleasedReturnValue;
200e7145dcbSDimitry Andric 
20117a519f9SDimitry Andric   /// A void(void) inline asm to use to mark that the return value of
20217a519f9SDimitry Andric   /// a call will be immediately retain.
20317a519f9SDimitry Andric   llvm::InlineAsm *retainAutoreleasedReturnValueMarker;
204139f7f9bSDimitry Andric 
205139f7f9bSDimitry Andric   /// void clang.arc.use(...);
206139f7f9bSDimitry Andric   llvm::Constant *clang_arc_use;
20717a519f9SDimitry Andric };
20817a519f9SDimitry Andric 
20959d1ed5bSDimitry Andric /// This class records statistics on instrumentation based profiling.
21059d1ed5bSDimitry Andric class InstrProfStats {
21159d1ed5bSDimitry Andric   uint32_t VisitedInMainFile;
21259d1ed5bSDimitry Andric   uint32_t MissingInMainFile;
21359d1ed5bSDimitry Andric   uint32_t Visited;
21459d1ed5bSDimitry Andric   uint32_t Missing;
21559d1ed5bSDimitry Andric   uint32_t Mismatched;
21659d1ed5bSDimitry Andric 
21759d1ed5bSDimitry Andric public:
InstrProfStats()21859d1ed5bSDimitry Andric   InstrProfStats()
21959d1ed5bSDimitry Andric       : VisitedInMainFile(0), MissingInMainFile(0), Visited(0), Missing(0),
22059d1ed5bSDimitry Andric         Mismatched(0) {}
22159d1ed5bSDimitry Andric   /// Record that we've visited a function and whether or not that function was
22259d1ed5bSDimitry Andric   /// in the main source file.
addVisited(bool MainFile)22359d1ed5bSDimitry Andric   void addVisited(bool MainFile) {
22459d1ed5bSDimitry Andric     if (MainFile)
22559d1ed5bSDimitry Andric       ++VisitedInMainFile;
22659d1ed5bSDimitry Andric     ++Visited;
22759d1ed5bSDimitry Andric   }
22859d1ed5bSDimitry Andric   /// Record that a function we've visited has no profile data.
addMissing(bool MainFile)22959d1ed5bSDimitry Andric   void addMissing(bool MainFile) {
23059d1ed5bSDimitry Andric     if (MainFile)
23159d1ed5bSDimitry Andric       ++MissingInMainFile;
23259d1ed5bSDimitry Andric     ++Missing;
23359d1ed5bSDimitry Andric   }
23459d1ed5bSDimitry Andric   /// Record that a function we've visited has mismatched profile data.
addMismatched(bool MainFile)23559d1ed5bSDimitry Andric   void addMismatched(bool MainFile) { ++Mismatched; }
23659d1ed5bSDimitry Andric   /// Whether or not the stats we've gathered indicate any potential problems.
hasDiagnostics()23759d1ed5bSDimitry Andric   bool hasDiagnostics() { return Missing || Mismatched; }
23859d1ed5bSDimitry Andric   /// Report potential problems we've found to \c Diags.
23959d1ed5bSDimitry Andric   void reportDiagnostics(DiagnosticsEngine &Diags, StringRef MainFile);
24059d1ed5bSDimitry Andric };
24159d1ed5bSDimitry Andric 
2420623d748SDimitry Andric /// A pair of helper functions for a __block variable.
2430623d748SDimitry Andric class BlockByrefHelpers : public llvm::FoldingSetNode {
2440623d748SDimitry Andric   // MSVC requires this type to be complete in order to process this
2450623d748SDimitry Andric   // header.
2460623d748SDimitry Andric public:
2470623d748SDimitry Andric   llvm::Constant *CopyHelper;
2480623d748SDimitry Andric   llvm::Constant *DisposeHelper;
2490623d748SDimitry Andric 
2500623d748SDimitry Andric   /// The alignment of the field.  This is important because
2510623d748SDimitry Andric   /// different offsets to the field within the byref struct need to
2520623d748SDimitry Andric   /// have different helper functions.
2530623d748SDimitry Andric   CharUnits Alignment;
2540623d748SDimitry Andric 
BlockByrefHelpers(CharUnits alignment)2550623d748SDimitry Andric   BlockByrefHelpers(CharUnits alignment) : Alignment(alignment) {}
2560623d748SDimitry Andric   BlockByrefHelpers(const BlockByrefHelpers &) = default;
2570623d748SDimitry Andric   virtual ~BlockByrefHelpers();
2580623d748SDimitry Andric 
Profile(llvm::FoldingSetNodeID & id)2590623d748SDimitry Andric   void Profile(llvm::FoldingSetNodeID &id) const {
2600623d748SDimitry Andric     id.AddInteger(Alignment.getQuantity());
2610623d748SDimitry Andric     profileImpl(id);
2620623d748SDimitry Andric   }
2630623d748SDimitry Andric   virtual void profileImpl(llvm::FoldingSetNodeID &id) const = 0;
2640623d748SDimitry Andric 
needsCopy()2650623d748SDimitry Andric   virtual bool needsCopy() const { return true; }
2660623d748SDimitry Andric   virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src) = 0;
2670623d748SDimitry Andric 
needsDispose()2680623d748SDimitry Andric   virtual bool needsDispose() const { return true; }
2690623d748SDimitry Andric   virtual void emitDispose(CodeGenFunction &CGF, Address field) = 0;
2700623d748SDimitry Andric };
2710623d748SDimitry Andric 
27259d1ed5bSDimitry Andric /// This class organizes the cross-function state that is used while generating
27359d1ed5bSDimitry Andric /// LLVM code.
2742754fe60SDimitry Andric class CodeGenModule : public CodeGenTypeCache {
27533956c43SDimitry Andric   CodeGenModule(const CodeGenModule &) = delete;
27633956c43SDimitry Andric   void operator=(const CodeGenModule &) = delete;
277f22ef01cSRoman Divacky 
27839d628a0SDimitry Andric public:
27959d1ed5bSDimitry Andric   struct Structor {
StructorStructor28059d1ed5bSDimitry Andric     Structor() : Priority(0), Initializer(nullptr), AssociatedData(nullptr) {}
StructorStructor28159d1ed5bSDimitry Andric     Structor(int Priority, llvm::Constant *Initializer,
28259d1ed5bSDimitry Andric              llvm::Constant *AssociatedData)
28359d1ed5bSDimitry Andric         : Priority(Priority), Initializer(Initializer),
28459d1ed5bSDimitry Andric           AssociatedData(AssociatedData) {}
28559d1ed5bSDimitry Andric     int Priority;
28659d1ed5bSDimitry Andric     llvm::Constant *Initializer;
28759d1ed5bSDimitry Andric     llvm::Constant *AssociatedData;
28859d1ed5bSDimitry Andric   };
28959d1ed5bSDimitry Andric 
29059d1ed5bSDimitry Andric   typedef std::vector<Structor> CtorList;
291f22ef01cSRoman Divacky 
29239d628a0SDimitry Andric private:
293f22ef01cSRoman Divacky   ASTContext &Context;
294dff0c46cSDimitry Andric   const LangOptions &LangOpts;
2953dac3a9bSDimitry Andric   const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info.
2963dac3a9bSDimitry Andric   const PreprocessorOptions &PreprocessorOpts; // Only used for debug info.
297f22ef01cSRoman Divacky   const CodeGenOptions &CodeGenOpts;
298f22ef01cSRoman Divacky   llvm::Module &TheModule;
2996122f3e6SDimitry Andric   DiagnosticsEngine &Diags;
300284c1978SDimitry Andric   const TargetInfo &Target;
30159d1ed5bSDimitry Andric   std::unique_ptr<CGCXXABI> ABI;
302284c1978SDimitry Andric   llvm::LLVMContext &VMContext;
303284c1978SDimitry Andric 
304e7145dcbSDimitry Andric   std::unique_ptr<CodeGenTBAA> TBAA;
305f22ef01cSRoman Divacky 
306e7145dcbSDimitry Andric   mutable std::unique_ptr<TargetCodeGenInfo> TheTargetCodeGenInfo;
307284c1978SDimitry Andric 
308284c1978SDimitry Andric   // This should not be moved earlier, since its initialization depends on some
309284c1978SDimitry Andric   // of the previous reference members being already initialized and also checks
310284c1978SDimitry Andric   // if TheTargetCodeGenInfo is NULL
311284c1978SDimitry Andric   CodeGenTypes Types;
312284c1978SDimitry Andric 
31359d1ed5bSDimitry Andric   /// Holds information about C++ vtables.
314f22ef01cSRoman Divacky   CodeGenVTables VTables;
315f22ef01cSRoman Divacky 
316e7145dcbSDimitry Andric   std::unique_ptr<CGObjCRuntime> ObjCRuntime;
317e7145dcbSDimitry Andric   std::unique_ptr<CGOpenCLRuntime> OpenCLRuntime;
318e7145dcbSDimitry Andric   std::unique_ptr<CGOpenMPRuntime> OpenMPRuntime;
319e7145dcbSDimitry Andric   std::unique_ptr<CGCUDARuntime> CUDARuntime;
320e7145dcbSDimitry Andric   std::unique_ptr<CGDebugInfo> DebugInfo;
321e7145dcbSDimitry Andric   std::unique_ptr<ObjCEntrypoints> ObjCData;
322e7145dcbSDimitry Andric   llvm::MDNode *NoObjCARCExceptionsMetadata = nullptr;
32359d1ed5bSDimitry Andric   std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader;
32459d1ed5bSDimitry Andric   InstrProfStats PGOStats;
325e7145dcbSDimitry Andric   std::unique_ptr<llvm::SanitizerStatReport> SanStats;
326f22ef01cSRoman Divacky 
32759d1ed5bSDimitry Andric   // A set of references that have only been seen via a weakref so far. This is
32859d1ed5bSDimitry Andric   // used to remove the weak of the reference if we ever see a direct reference
32959d1ed5bSDimitry Andric   // or a definition.
330f22ef01cSRoman Divacky   llvm::SmallPtrSet<llvm::GlobalValue*, 10> WeakRefReferences;
331f22ef01cSRoman Divacky 
33259d1ed5bSDimitry Andric   /// This contains all the decls which have definitions but/ which are deferred
33359d1ed5bSDimitry Andric   /// for emission and therefore should only be output if they are actually
33459d1ed5bSDimitry Andric   /// used. If a decl is in this, then it is known to have not been referenced
33559d1ed5bSDimitry Andric   /// yet.
33659d1ed5bSDimitry Andric   std::map<StringRef, GlobalDecl> DeferredDecls;
337f22ef01cSRoman Divacky 
33859d1ed5bSDimitry Andric   /// This is a list of deferred decls which we have seen that *are* actually
33959d1ed5bSDimitry Andric   /// referenced. These get code generated when the module is done.
340f37b6182SDimitry Andric   std::vector<GlobalDecl> DeferredDeclsToEmit;
addDeferredDeclToEmit(GlobalDecl GD)341f37b6182SDimitry Andric   void addDeferredDeclToEmit(GlobalDecl GD) {
342f37b6182SDimitry Andric     DeferredDeclsToEmit.emplace_back(GD);
34359d1ed5bSDimitry Andric   }
344f22ef01cSRoman Divacky 
345f785676fSDimitry Andric   /// List of alias we have emitted. Used to make sure that what they point to
346f785676fSDimitry Andric   /// is defined once we get to the end of the of the translation unit.
347f785676fSDimitry Andric   std::vector<GlobalDecl> Aliases;
348f785676fSDimitry Andric 
3494ba319b5SDimitry Andric   /// List of multiversion functions that have to be emitted.  Used to make sure
3504ba319b5SDimitry Andric   /// we properly emit the iFunc.
3514ba319b5SDimitry Andric   std::vector<GlobalDecl> MultiVersionFuncs;
3524ba319b5SDimitry Andric 
353f785676fSDimitry Andric   typedef llvm::StringMap<llvm::TrackingVH<llvm::Constant> > ReplacementsTy;
354f785676fSDimitry Andric   ReplacementsTy Replacements;
355f785676fSDimitry Andric 
3560623d748SDimitry Andric   /// List of global values to be replaced with something else. Used when we
3570623d748SDimitry Andric   /// want to replace a GlobalValue but can't identify it by its mangled name
3580623d748SDimitry Andric   /// anymore (because the name is already taken).
3590623d748SDimitry Andric   llvm::SmallVector<std::pair<llvm::GlobalValue *, llvm::Constant *>, 8>
3600623d748SDimitry Andric     GlobalValReplacements;
3610623d748SDimitry Andric 
3620623d748SDimitry Andric   /// Set of global decls for which we already diagnosed mangled name conflict.
3630623d748SDimitry Andric   /// Required to not issue a warning (on a mangling conflict) multiple times
3640623d748SDimitry Andric   /// for the same decl.
3650623d748SDimitry Andric   llvm::DenseSet<GlobalDecl> DiagnosedConflictingDefinitions;
3660623d748SDimitry Andric 
36759d1ed5bSDimitry Andric   /// A queue of (optional) vtables to consider emitting.
368139f7f9bSDimitry Andric   std::vector<const CXXRecordDecl*> DeferredVTables;
369139f7f9bSDimitry Andric 
370f9448bf3SDimitry Andric   /// A queue of (optional) vtables that may be emitted opportunistically.
371f9448bf3SDimitry Andric   std::vector<const CXXRecordDecl *> OpportunisticVTables;
372f9448bf3SDimitry Andric 
37359d1ed5bSDimitry Andric   /// List of global values which are required to be present in the object file;
37459d1ed5bSDimitry Andric   /// bitcast to i8*. This is used for forcing visibility of symbols which may
37559d1ed5bSDimitry Andric   /// otherwise be optimized out.
376f37b6182SDimitry Andric   std::vector<llvm::WeakTrackingVH> LLVMUsed;
377f37b6182SDimitry Andric   std::vector<llvm::WeakTrackingVH> LLVMCompilerUsed;
378f22ef01cSRoman Divacky 
37959d1ed5bSDimitry Andric   /// Store the list of global constructors and their respective priorities to
38059d1ed5bSDimitry Andric   /// be emitted when the translation unit is complete.
381f22ef01cSRoman Divacky   CtorList GlobalCtors;
382f22ef01cSRoman Divacky 
38359d1ed5bSDimitry Andric   /// Store the list of global destructors and their respective priorities to be
38459d1ed5bSDimitry Andric   /// emitted when the translation unit is complete.
385f22ef01cSRoman Divacky   CtorList GlobalDtors;
386f22ef01cSRoman Divacky 
38759d1ed5bSDimitry Andric   /// An ordered map of canonical GlobalDecls to their mangled names.
38859d1ed5bSDimitry Andric   llvm::MapVector<GlobalDecl, StringRef> MangledDeclNames;
38959d1ed5bSDimitry Andric   llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings;
390ffd1746dSEd Schouten 
3914ba319b5SDimitry Andric   // An ordered map of canonical GlobalDecls paired with the cpu-index for
3924ba319b5SDimitry Andric   // cpu-specific name manglings.
3934ba319b5SDimitry Andric   llvm::MapVector<std::pair<GlobalDecl, unsigned>, StringRef>
3944ba319b5SDimitry Andric       CPUSpecificMangledDeclNames;
3954ba319b5SDimitry Andric   llvm::StringMap<std::pair<GlobalDecl, unsigned>, llvm::BumpPtrAllocator>
3964ba319b5SDimitry Andric       CPUSpecificManglings;
3974ba319b5SDimitry Andric 
3986122f3e6SDimitry Andric   /// Global annotations.
399f22ef01cSRoman Divacky   std::vector<llvm::Constant*> Annotations;
400f22ef01cSRoman Divacky 
4016122f3e6SDimitry Andric   /// Map used to get unique annotation strings.
4026122f3e6SDimitry Andric   llvm::StringMap<llvm::Constant*> AnnotationStrings;
4036122f3e6SDimitry Andric 
40433956c43SDimitry Andric   llvm::StringMap<llvm::GlobalVariable *> CFConstantStringMap;
40559d1ed5bSDimitry Andric 
40659d1ed5bSDimitry Andric   llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> ConstantStringMap;
407dff0c46cSDimitry Andric   llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap;
408dff0c46cSDimitry Andric   llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap;
409f785676fSDimitry Andric   llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap;
410dff0c46cSDimitry Andric 
411dff0c46cSDimitry Andric   llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap;
412dff0c46cSDimitry Andric   llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap;
413f22ef01cSRoman Divacky 
414f785676fSDimitry Andric   /// Map used to get unique type descriptor constants for sanitizers.
415f785676fSDimitry Andric   llvm::DenseMap<QualType, llvm::Constant *> TypeDescriptorMap;
416f785676fSDimitry Andric 
417284c1978SDimitry Andric   /// Map used to track internal linkage functions declared within
418284c1978SDimitry Andric   /// extern "C" regions.
419284c1978SDimitry Andric   typedef llvm::MapVector<IdentifierInfo *,
420284c1978SDimitry Andric                           llvm::GlobalValue *> StaticExternCMap;
421284c1978SDimitry Andric   StaticExternCMap StaticExternCValues;
422284c1978SDimitry Andric 
4234ba319b5SDimitry Andric   /// thread_local variables defined or used in this TU.
4240623d748SDimitry Andric   std::vector<const VarDecl *> CXXThreadLocals;
425284c1978SDimitry Andric 
4264ba319b5SDimitry Andric   /// thread_local variables with initializers that need to run
427284c1978SDimitry Andric   /// before any thread_local variable in this TU is odr-used.
42839d628a0SDimitry Andric   std::vector<llvm::Function *> CXXThreadLocalInits;
4290623d748SDimitry Andric   std::vector<const VarDecl *> CXXThreadLocalInitVars;
430284c1978SDimitry Andric 
43159d1ed5bSDimitry Andric   /// Global variables with initializers that need to run before main.
43239d628a0SDimitry Andric   std::vector<llvm::Function *> CXXGlobalInits;
433f22ef01cSRoman Divacky 
434e580952dSDimitry Andric   /// When a C++ decl with an initializer is deferred, null is
435e580952dSDimitry Andric   /// appended to CXXGlobalInits, and the index of that null is placed
436e580952dSDimitry Andric   /// here so that the initializer will be performed in the correct
43733956c43SDimitry Andric   /// order. Once the decl is emitted, the index is replaced with ~0U to ensure
43833956c43SDimitry Andric   /// that we don't re-emit the initializer.
439e580952dSDimitry Andric   llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition;
440e580952dSDimitry Andric 
4413861d79fSDimitry Andric   typedef std::pair<OrderGlobalInits, llvm::Function*> GlobalInitData;
4423861d79fSDimitry Andric 
4433861d79fSDimitry Andric   struct GlobalInitPriorityCmp {
operatorGlobalInitPriorityCmp4443861d79fSDimitry Andric     bool operator()(const GlobalInitData &LHS,
4453861d79fSDimitry Andric                     const GlobalInitData &RHS) const {
4463861d79fSDimitry Andric       return LHS.first.priority < RHS.first.priority;
4473861d79fSDimitry Andric     }
4483861d79fSDimitry Andric   };
4493861d79fSDimitry Andric 
45059d1ed5bSDimitry Andric   /// Global variables with initializers whose order of initialization is set by
45159d1ed5bSDimitry Andric   /// init_priority attribute.
4523861d79fSDimitry Andric   SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits;
453ffd1746dSEd Schouten 
45459d1ed5bSDimitry Andric   /// Global destructor functions and arguments that need to run on termination.
455f37b6182SDimitry Andric   std::vector<std::pair<llvm::WeakTrackingVH, llvm::Constant *>> CXXGlobalDtors;
456f22ef01cSRoman Divacky 
4574ba319b5SDimitry Andric   /// The complete set of modules that has been imported.
458139f7f9bSDimitry Andric   llvm::SetVector<clang::Module *> ImportedModules;
459139f7f9bSDimitry Andric 
4604ba319b5SDimitry Andric   /// The set of modules for which the module initializers
46144290647SDimitry Andric   /// have been emitted.
46244290647SDimitry Andric   llvm::SmallPtrSet<clang::Module *, 16> EmittedModuleInitializers;
46344290647SDimitry Andric 
4644ba319b5SDimitry Andric   /// A vector of metadata strings.
46524d58133SDimitry Andric   SmallVector<llvm::MDNode *, 16> LinkerOptionsMetadata;
466f785676fSDimitry Andric 
4676122f3e6SDimitry Andric   /// @name Cache for Objective-C runtime types
4686122f3e6SDimitry Andric   /// @{
4696122f3e6SDimitry Andric 
47059d1ed5bSDimitry Andric   /// Cached reference to the class for constant strings. This value has type
47159d1ed5bSDimitry Andric   /// int * but is actually an Obj-C class pointer.
472f37b6182SDimitry Andric   llvm::WeakTrackingVH CFConstantStringClassRef;
473f22ef01cSRoman Divacky 
4744ba319b5SDimitry Andric   /// The type used to describe the state of a fast enumeration in
4756122f3e6SDimitry Andric   /// Objective-C's for..in loop.
4766122f3e6SDimitry Andric   QualType ObjCFastEnumerationStateType;
4776122f3e6SDimitry Andric 
4786122f3e6SDimitry Andric   /// @}
4796122f3e6SDimitry Andric 
480f22ef01cSRoman Divacky   /// Lazily create the Objective-C runtime
481f22ef01cSRoman Divacky   void createObjCRuntime();
482f22ef01cSRoman Divacky 
4836122f3e6SDimitry Andric   void createOpenCLRuntime();
48459d1ed5bSDimitry Andric   void createOpenMPRuntime();
4856122f3e6SDimitry Andric   void createCUDARuntime();
4866122f3e6SDimitry Andric 
487dff0c46cSDimitry Andric   bool isTriviallyRecursive(const FunctionDecl *F);
488f785676fSDimitry Andric   bool shouldEmitFunction(GlobalDecl GD);
489f9448bf3SDimitry Andric   bool shouldOpportunisticallyEmitVTables();
49044290647SDimitry Andric   /// Map used to be sure we don't emit the same CompoundLiteral twice.
49144290647SDimitry Andric   llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *>
49244290647SDimitry Andric       EmittedCompoundLiterals;
49344290647SDimitry Andric 
49444290647SDimitry Andric   /// Map of the global blocks we've emitted, so that we don't have to re-emit
49544290647SDimitry Andric   /// them if the constexpr evaluator gets aggressive.
49644290647SDimitry Andric   llvm::DenseMap<const BlockExpr *, llvm::Constant *> EmittedGlobalBlocks;
49744290647SDimitry Andric 
498e580952dSDimitry Andric   /// @name Cache for Blocks Runtime Globals
499e580952dSDimitry Andric   /// @{
500e580952dSDimitry Andric 
501e7145dcbSDimitry Andric   llvm::Constant *NSConcreteGlobalBlock = nullptr;
502e7145dcbSDimitry Andric   llvm::Constant *NSConcreteStackBlock = nullptr;
503e580952dSDimitry Andric 
504e7145dcbSDimitry Andric   llvm::Constant *BlockObjectAssign = nullptr;
505e7145dcbSDimitry Andric   llvm::Constant *BlockObjectDispose = nullptr;
506e580952dSDimitry Andric 
507e7145dcbSDimitry Andric   llvm::Type *BlockDescriptorType = nullptr;
508e7145dcbSDimitry Andric   llvm::Type *GenericBlockLiteralType = nullptr;
5092754fe60SDimitry Andric 
5102754fe60SDimitry Andric   struct {
5112754fe60SDimitry Andric     int GlobalUniqueCount;
5122754fe60SDimitry Andric   } Block;
5132754fe60SDimitry Andric 
514139f7f9bSDimitry Andric   /// void @llvm.lifetime.start(i64 %size, i8* nocapture <ptr>)
515e7145dcbSDimitry Andric   llvm::Constant *LifetimeStartFn = nullptr;
516139f7f9bSDimitry Andric 
517139f7f9bSDimitry Andric   /// void @llvm.lifetime.end(i64 %size, i8* nocapture <ptr>)
518e7145dcbSDimitry Andric   llvm::Constant *LifetimeEndFn = nullptr;
519139f7f9bSDimitry Andric 
5207ae0e2c9SDimitry Andric   GlobalDecl initializedGlobalDecl;
5217ae0e2c9SDimitry Andric 
52239d628a0SDimitry Andric   std::unique_ptr<SanitizerMetadata> SanitizerMD;
523139f7f9bSDimitry Andric 
524e580952dSDimitry Andric   /// @}
52539d628a0SDimitry Andric 
5269a199699SDimitry Andric   llvm::MapVector<const Decl *, bool> DeferredEmptyCoverageMappingDecls;
52739d628a0SDimitry Andric 
52839d628a0SDimitry Andric   std::unique_ptr<CoverageMappingModuleGen> CoverageMapping;
5290623d748SDimitry Andric 
5300623d748SDimitry Andric   /// Mapping from canonical types to their metadata identifiers. We need to
5310623d748SDimitry Andric   /// maintain this mapping because identifiers may be formed from distinct
5320623d748SDimitry Andric   /// MDNodes.
5339a199699SDimitry Andric   typedef llvm::DenseMap<QualType, llvm::Metadata *> MetadataTypeMap;
5349a199699SDimitry Andric   MetadataTypeMap MetadataIdMap;
5354ba319b5SDimitry Andric   MetadataTypeMap VirtualMetadataIdMap;
5369a199699SDimitry Andric   MetadataTypeMap GeneralizedMetadataIdMap;
5370623d748SDimitry Andric 
538f22ef01cSRoman Divacky public:
5390623d748SDimitry Andric   CodeGenModule(ASTContext &C, const HeaderSearchOptions &headersearchopts,
5403dac3a9bSDimitry Andric                 const PreprocessorOptions &ppopts,
5410623d748SDimitry Andric                 const CodeGenOptions &CodeGenOpts, llvm::Module &M,
54239d628a0SDimitry Andric                 DiagnosticsEngine &Diags,
54339d628a0SDimitry Andric                 CoverageSourceInfo *CoverageInfo = nullptr);
544f22ef01cSRoman Divacky 
545f22ef01cSRoman Divacky   ~CodeGenModule();
546f22ef01cSRoman Divacky 
54759d1ed5bSDimitry Andric   void clear();
54859d1ed5bSDimitry Andric 
54959d1ed5bSDimitry Andric   /// Finalize LLVM code generation.
550f22ef01cSRoman Divacky   void Release();
551f22ef01cSRoman Divacky 
5529a199699SDimitry Andric   /// Return true if we should emit location information for expressions.
5539a199699SDimitry Andric   bool getExpressionLocationsEnabled() const;
5549a199699SDimitry Andric 
55559d1ed5bSDimitry Andric   /// Return a reference to the configured Objective-C runtime.
getObjCRuntime()556f22ef01cSRoman Divacky   CGObjCRuntime &getObjCRuntime() {
5576122f3e6SDimitry Andric     if (!ObjCRuntime) createObjCRuntime();
5586122f3e6SDimitry Andric     return *ObjCRuntime;
559f22ef01cSRoman Divacky   }
560f22ef01cSRoman Divacky 
56159d1ed5bSDimitry Andric   /// Return true iff an Objective-C runtime has been configured.
hasObjCRuntime()5626122f3e6SDimitry Andric   bool hasObjCRuntime() { return !!ObjCRuntime; }
5636122f3e6SDimitry Andric 
56459d1ed5bSDimitry Andric   /// Return a reference to the configured OpenCL runtime.
getOpenCLRuntime()5656122f3e6SDimitry Andric   CGOpenCLRuntime &getOpenCLRuntime() {
56659d1ed5bSDimitry Andric     assert(OpenCLRuntime != nullptr);
5676122f3e6SDimitry Andric     return *OpenCLRuntime;
5686122f3e6SDimitry Andric   }
5696122f3e6SDimitry Andric 
57059d1ed5bSDimitry Andric   /// Return a reference to the configured OpenMP runtime.
getOpenMPRuntime()57159d1ed5bSDimitry Andric   CGOpenMPRuntime &getOpenMPRuntime() {
57259d1ed5bSDimitry Andric     assert(OpenMPRuntime != nullptr);
57359d1ed5bSDimitry Andric     return *OpenMPRuntime;
57459d1ed5bSDimitry Andric   }
57559d1ed5bSDimitry Andric 
57659d1ed5bSDimitry Andric   /// Return a reference to the configured CUDA runtime.
getCUDARuntime()5776122f3e6SDimitry Andric   CGCUDARuntime &getCUDARuntime() {
57859d1ed5bSDimitry Andric     assert(CUDARuntime != nullptr);
5796122f3e6SDimitry Andric     return *CUDARuntime;
5806122f3e6SDimitry Andric   }
581f22ef01cSRoman Divacky 
getObjCEntrypoints()5820623d748SDimitry Andric   ObjCEntrypoints &getObjCEntrypoints() const {
5830623d748SDimitry Andric     assert(ObjCData != nullptr);
5840623d748SDimitry Andric     return *ObjCData;
58517a519f9SDimitry Andric   }
58617a519f9SDimitry Andric 
58720e90f04SDimitry Andric   // Version checking function, used to implement ObjC's @available:
58820e90f04SDimitry Andric   // i32 @__isOSVersionAtLeast(i32, i32, i32)
58920e90f04SDimitry Andric   llvm::Constant *IsOSVersionAtLeastFn = nullptr;
59020e90f04SDimitry Andric 
getPGOStats()59159d1ed5bSDimitry Andric   InstrProfStats &getPGOStats() { return PGOStats; }
getPGOReader()59259d1ed5bSDimitry Andric   llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); }
59359d1ed5bSDimitry Andric 
getCoverageMapping()59439d628a0SDimitry Andric   CoverageMappingModuleGen *getCoverageMapping() const {
59539d628a0SDimitry Andric     return CoverageMapping.get();
59639d628a0SDimitry Andric   }
59739d628a0SDimitry Andric 
getStaticLocalDeclAddress(const VarDecl * D)598dff0c46cSDimitry Andric   llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {
599dff0c46cSDimitry Andric     return StaticLocalDeclMap[D];
600f22ef01cSRoman Divacky   }
setStaticLocalDeclAddress(const VarDecl * D,llvm::Constant * C)601f22ef01cSRoman Divacky   void setStaticLocalDeclAddress(const VarDecl *D,
602dff0c46cSDimitry Andric                                  llvm::Constant *C) {
603dff0c46cSDimitry Andric     StaticLocalDeclMap[D] = C;
604dff0c46cSDimitry Andric   }
605dff0c46cSDimitry Andric 
60639d628a0SDimitry Andric   llvm::Constant *
60739d628a0SDimitry Andric   getOrCreateStaticVarDecl(const VarDecl &D,
60839d628a0SDimitry Andric                            llvm::GlobalValue::LinkageTypes Linkage);
60939d628a0SDimitry Andric 
getStaticLocalDeclGuardAddress(const VarDecl * D)610dff0c46cSDimitry Andric   llvm::GlobalVariable *getStaticLocalDeclGuardAddress(const VarDecl *D) {
611dff0c46cSDimitry Andric     return StaticLocalDeclGuardMap[D];
612dff0c46cSDimitry Andric   }
setStaticLocalDeclGuardAddress(const VarDecl * D,llvm::GlobalVariable * C)613dff0c46cSDimitry Andric   void setStaticLocalDeclGuardAddress(const VarDecl *D,
614dff0c46cSDimitry Andric                                       llvm::GlobalVariable *C) {
615dff0c46cSDimitry Andric     StaticLocalDeclGuardMap[D] = C;
616dff0c46cSDimitry Andric   }
617dff0c46cSDimitry Andric 
61859d1ed5bSDimitry Andric   bool lookupRepresentativeDecl(StringRef MangledName,
61959d1ed5bSDimitry Andric                                 GlobalDecl &Result) const;
62059d1ed5bSDimitry Andric 
getAtomicSetterHelperFnMap(QualType Ty)621dff0c46cSDimitry Andric   llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) {
622dff0c46cSDimitry Andric     return AtomicSetterHelperFnMap[Ty];
623dff0c46cSDimitry Andric   }
setAtomicSetterHelperFnMap(QualType Ty,llvm::Constant * Fn)624dff0c46cSDimitry Andric   void setAtomicSetterHelperFnMap(QualType Ty,
625dff0c46cSDimitry Andric                             llvm::Constant *Fn) {
626dff0c46cSDimitry Andric     AtomicSetterHelperFnMap[Ty] = Fn;
627dff0c46cSDimitry Andric   }
628dff0c46cSDimitry Andric 
getAtomicGetterHelperFnMap(QualType Ty)629dff0c46cSDimitry Andric   llvm::Constant *getAtomicGetterHelperFnMap(QualType Ty) {
630dff0c46cSDimitry Andric     return AtomicGetterHelperFnMap[Ty];
631dff0c46cSDimitry Andric   }
setAtomicGetterHelperFnMap(QualType Ty,llvm::Constant * Fn)632dff0c46cSDimitry Andric   void setAtomicGetterHelperFnMap(QualType Ty,
633dff0c46cSDimitry Andric                             llvm::Constant *Fn) {
634dff0c46cSDimitry Andric     AtomicGetterHelperFnMap[Ty] = Fn;
635f22ef01cSRoman Divacky   }
636f22ef01cSRoman Divacky 
getTypeDescriptorFromMap(QualType Ty)63759d1ed5bSDimitry Andric   llvm::Constant *getTypeDescriptorFromMap(QualType Ty) {
638f785676fSDimitry Andric     return TypeDescriptorMap[Ty];
639f785676fSDimitry Andric   }
setTypeDescriptorInMap(QualType Ty,llvm::Constant * C)64059d1ed5bSDimitry Andric   void setTypeDescriptorInMap(QualType Ty, llvm::Constant *C) {
641f785676fSDimitry Andric     TypeDescriptorMap[Ty] = C;
642f785676fSDimitry Andric   }
643f785676fSDimitry Andric 
getModuleDebugInfo()644e7145dcbSDimitry Andric   CGDebugInfo *getModuleDebugInfo() { return DebugInfo.get(); }
6453b0f4066SDimitry Andric 
getNoObjCARCExceptionsMetadata()646dff0c46cSDimitry Andric   llvm::MDNode *getNoObjCARCExceptionsMetadata() {
647dff0c46cSDimitry Andric     if (!NoObjCARCExceptionsMetadata)
64839d628a0SDimitry Andric       NoObjCARCExceptionsMetadata = llvm::MDNode::get(getLLVMContext(), None);
649dff0c46cSDimitry Andric     return NoObjCARCExceptionsMetadata;
650dff0c46cSDimitry Andric   }
651dff0c46cSDimitry Andric 
getContext()652f22ef01cSRoman Divacky   ASTContext &getContext() const { return Context; }
getLangOpts()653dff0c46cSDimitry Andric   const LangOptions &getLangOpts() const { return LangOpts; }
getHeaderSearchOpts()6543dac3a9bSDimitry Andric   const HeaderSearchOptions &getHeaderSearchOpts()
6553dac3a9bSDimitry Andric     const { return HeaderSearchOpts; }
getPreprocessorOpts()6563dac3a9bSDimitry Andric   const PreprocessorOptions &getPreprocessorOpts()
6573dac3a9bSDimitry Andric     const { return PreprocessorOpts; }
getCodeGenOpts()658284c1978SDimitry Andric   const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
getModule()659f22ef01cSRoman Divacky   llvm::Module &getModule() const { return TheModule; }
getDiags()6606122f3e6SDimitry Andric   DiagnosticsEngine &getDiags() const { return Diags; }
getDataLayout()6610623d748SDimitry Andric   const llvm::DataLayout &getDataLayout() const {
6620623d748SDimitry Andric     return TheModule.getDataLayout();
6630623d748SDimitry Andric   }
getTarget()664284c1978SDimitry Andric   const TargetInfo &getTarget() const { return Target; }
getTriple()66544290647SDimitry Andric   const llvm::Triple &getTriple() const { return Target.getTriple(); }
66639d628a0SDimitry Andric   bool supportsCOMDAT() const;
66733956c43SDimitry Andric   void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO);
66839d628a0SDimitry Andric 
getCXXABI()66959d1ed5bSDimitry Andric   CGCXXABI &getCXXABI() const { return *ABI; }
getLLVMContext()670f22ef01cSRoman Divacky   llvm::LLVMContext &getLLVMContext() { return VMContext; }
671f22ef01cSRoman Divacky 
shouldUseTBAA()67259d1ed5bSDimitry Andric   bool shouldUseTBAA() const { return TBAA != nullptr; }
673dd6029ffSDimitry Andric 
674284c1978SDimitry Andric   const TargetCodeGenInfo &getTargetCodeGenInfo();
675284c1978SDimitry Andric 
getTypes()676284c1978SDimitry Andric   CodeGenTypes &getTypes() { return Types; }
677284c1978SDimitry Andric 
getVTables()678284c1978SDimitry Andric   CodeGenVTables &getVTables() { return VTables; }
679f785676fSDimitry Andric 
getItaniumVTableContext()680f785676fSDimitry Andric   ItaniumVTableContext &getItaniumVTableContext() {
681f785676fSDimitry Andric     return VTables.getItaniumVTableContext();
682f785676fSDimitry Andric   }
683f785676fSDimitry Andric 
getMicrosoftVTableContext()684f785676fSDimitry Andric   MicrosoftVTableContext &getMicrosoftVTableContext() {
685f785676fSDimitry Andric     return VTables.getMicrosoftVTableContext();
686f785676fSDimitry Andric   }
687284c1978SDimitry Andric 
getGlobalCtors()68839d628a0SDimitry Andric   CtorList &getGlobalCtors() { return GlobalCtors; }
getGlobalDtors()68939d628a0SDimitry Andric   CtorList &getGlobalDtors() { return GlobalDtors; }
69039d628a0SDimitry Andric 
6919a199699SDimitry Andric   /// getTBAATypeInfo - Get metadata used to describe accesses to objects of
6929a199699SDimitry Andric   /// the given type.
6939a199699SDimitry Andric   llvm::MDNode *getTBAATypeInfo(QualType QTy);
6949a199699SDimitry Andric 
6959a199699SDimitry Andric   /// getTBAAAccessInfo - Get TBAA information that describes an access to
6969a199699SDimitry Andric   /// an object of the given type.
6979a199699SDimitry Andric   TBAAAccessInfo getTBAAAccessInfo(QualType AccessType);
6989a199699SDimitry Andric 
6999a199699SDimitry Andric   /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an
7009a199699SDimitry Andric   /// access to a virtual table pointer.
7019a199699SDimitry Andric   TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType);
7029a199699SDimitry Andric 
7033861d79fSDimitry Andric   llvm::MDNode *getTBAAStructInfo(QualType QTy);
7049a199699SDimitry Andric 
7059a199699SDimitry Andric   /// getTBAABaseTypeInfo - Get metadata that describes the given base access
7069a199699SDimitry Andric   /// type. Return null if the type is not suitable for use in TBAA access tags.
7079a199699SDimitry Andric   llvm::MDNode *getTBAABaseTypeInfo(QualType QTy);
7089a199699SDimitry Andric 
7099a199699SDimitry Andric   /// getTBAAAccessTagInfo - Get TBAA tag for a given memory access.
7109a199699SDimitry Andric   llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info);
7119a199699SDimitry Andric 
7129a199699SDimitry Andric   /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of
7139a199699SDimitry Andric   /// type casts.
7149a199699SDimitry Andric   TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
7159a199699SDimitry Andric                                       TBAAAccessInfo TargetInfo);
7169a199699SDimitry Andric 
7179a199699SDimitry Andric   /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the
7189a199699SDimitry Andric   /// purposes of conditional operator.
7199a199699SDimitry Andric   TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
7209a199699SDimitry Andric                                                      TBAAAccessInfo InfoB);
7219a199699SDimitry Andric 
7224ba319b5SDimitry Andric   /// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the
7234ba319b5SDimitry Andric   /// purposes of memory transfer calls.
7244ba319b5SDimitry Andric   TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
7254ba319b5SDimitry Andric                                                 TBAAAccessInfo SrcInfo);
7264ba319b5SDimitry Andric 
7279a199699SDimitry Andric   /// getTBAAInfoForSubobject - Get TBAA information for an access with a given
7289a199699SDimitry Andric   /// base lvalue.
getTBAAInfoForSubobject(LValue Base,QualType AccessType)7299a199699SDimitry Andric   TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType) {
7309a199699SDimitry Andric     if (Base.getTBAAInfo().isMayAlias())
7319a199699SDimitry Andric       return TBAAAccessInfo::getMayAliasInfo();
7329a199699SDimitry Andric     return getTBAAAccessInfo(AccessType);
7339a199699SDimitry Andric   }
734dff0c46cSDimitry Andric 
735dff0c46cSDimitry Andric   bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor);
7362754fe60SDimitry Andric 
737139f7f9bSDimitry Andric   bool isPaddedAtomicType(QualType type);
738139f7f9bSDimitry Andric   bool isPaddedAtomicType(const AtomicType *type);
739139f7f9bSDimitry Andric 
7409a199699SDimitry Andric   /// DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag.
7410623d748SDimitry Andric   void DecorateInstructionWithTBAA(llvm::Instruction *Inst,
7429a199699SDimitry Andric                                    TBAAAccessInfo TBAAInfo);
743f22ef01cSRoman Divacky 
7440623d748SDimitry Andric   /// Adds !invariant.barrier !tag to instruction
7450623d748SDimitry Andric   void DecorateInstructionWithInvariantGroup(llvm::Instruction *I,
7460623d748SDimitry Andric                                              const CXXRecordDecl *RD);
7470623d748SDimitry Andric 
74859d1ed5bSDimitry Andric   /// Emit the given number of characters as a value of type size_t.
74917a519f9SDimitry Andric   llvm::ConstantInt *getSize(CharUnits numChars);
75017a519f9SDimitry Andric 
75159d1ed5bSDimitry Andric   /// Set the visibility for the given LLVM GlobalValue.
7524ba319b5SDimitry Andric   void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const;
7534ba319b5SDimitry Andric 
7544ba319b5SDimitry Andric   void setGlobalVisibilityAndLocal(llvm::GlobalValue *GV,
7554ba319b5SDimitry Andric                                    const NamedDecl *D) const;
7564ba319b5SDimitry Andric 
7574ba319b5SDimitry Andric   void setDSOLocal(llvm::GlobalValue *GV) const;
7584ba319b5SDimitry Andric 
7594ba319b5SDimitry Andric   void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const;
7604ba319b5SDimitry Andric   void setDLLImportDLLExport(llvm::GlobalValue *GV, const NamedDecl *D) const;
7614ba319b5SDimitry Andric   /// Set visibility, dllimport/dllexport and dso_local.
7624ba319b5SDimitry Andric   /// This must be called after dllimport/dllexport is set.
7634ba319b5SDimitry Andric   void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const;
7644ba319b5SDimitry Andric   void setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D) const;
7652754fe60SDimitry Andric 
76639d628a0SDimitry Andric   /// Set the TLS mode for the given LLVM GlobalValue for the thread-local
76759d1ed5bSDimitry Andric   /// variable declaration D.
76839d628a0SDimitry Andric   void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const;
7697ae0e2c9SDimitry Andric 
GetLLVMVisibility(Visibility V)7702754fe60SDimitry Andric   static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) {
7712754fe60SDimitry Andric     switch (V) {
7722754fe60SDimitry Andric     case DefaultVisibility:   return llvm::GlobalValue::DefaultVisibility;
7732754fe60SDimitry Andric     case HiddenVisibility:    return llvm::GlobalValue::HiddenVisibility;
7742754fe60SDimitry Andric     case ProtectedVisibility: return llvm::GlobalValue::ProtectedVisibility;
7752754fe60SDimitry Andric     }
7762754fe60SDimitry Andric     llvm_unreachable("unknown visibility!");
7772754fe60SDimitry Andric   }
778e580952dSDimitry Andric 
77944290647SDimitry Andric   llvm::Constant *GetAddrOfGlobal(GlobalDecl GD,
78044290647SDimitry Andric                                   ForDefinition_t IsForDefinition
78144290647SDimitry Andric                                     = NotForDefinition);
782f22ef01cSRoman Divacky 
78359d1ed5bSDimitry Andric   /// Will return a global variable of the given type. If a variable with a
78459d1ed5bSDimitry Andric   /// different type already exists then a new  variable with the right type
78559d1ed5bSDimitry Andric   /// will be created and all uses of the old variable will be replaced with a
78659d1ed5bSDimitry Andric   /// bitcast to the new variable.
7872754fe60SDimitry Andric   llvm::GlobalVariable *
7886122f3e6SDimitry Andric   CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty,
789*b5893f02SDimitry Andric                                     llvm::GlobalValue::LinkageTypes Linkage,
790*b5893f02SDimitry Andric                                     unsigned Alignment);
7912754fe60SDimitry Andric 
79239d628a0SDimitry Andric   llvm::Function *
79339d628a0SDimitry Andric   CreateGlobalInitOrDestructFunction(llvm::FunctionType *ty, const Twine &name,
7940623d748SDimitry Andric                                      const CGFunctionInfo &FI,
79539d628a0SDimitry Andric                                      SourceLocation Loc = SourceLocation(),
79639d628a0SDimitry Andric                                      bool TLS = false);
79739d628a0SDimitry Andric 
798c4394386SDimitry Andric   /// Return the AST address space of the underlying global variable for D, as
79959d1ed5bSDimitry Andric   /// determined by its declaration. Normally this is the same as the address
80059d1ed5bSDimitry Andric   /// space of D's type, but in CUDA, address spaces are associated with
801c4394386SDimitry Andric   /// declarations, not types. If D is nullptr, return the default address
802c4394386SDimitry Andric   /// space for global variable.
803c4394386SDimitry Andric   ///
804c4394386SDimitry Andric   /// For languages without explicit address spaces, if D has default address
805c4394386SDimitry Andric   /// space, target-specific global or constant address space may be returned.
8069a199699SDimitry Andric   LangAS GetGlobalVarAddressSpace(const VarDecl *D);
8077ae0e2c9SDimitry Andric 
80859d1ed5bSDimitry Andric   /// Return the llvm::Constant for the address of the given global variable.
809e7145dcbSDimitry Andric   /// If Ty is non-null and if the global doesn't exist, then it will be created
81059d1ed5bSDimitry Andric   /// with the specified type instead of whatever the normal requested type
8114ba319b5SDimitry Andric   /// would be. If IsForDefinition is true, it is guaranteed that an actual
812e7145dcbSDimitry Andric   /// global with type Ty will be returned, not conversion of a variable with
813e7145dcbSDimitry Andric   /// the same mangled name but some other type.
814f22ef01cSRoman Divacky   llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D,
815e7145dcbSDimitry Andric                                      llvm::Type *Ty = nullptr,
81644290647SDimitry Andric                                      ForDefinition_t IsForDefinition
81744290647SDimitry Andric                                        = NotForDefinition);
818f22ef01cSRoman Divacky 
8194ba319b5SDimitry Andric   /// Return the AST address space of string literal, which is used to emit
8204ba319b5SDimitry Andric   /// the string literal as global variable in LLVM IR.
8214ba319b5SDimitry Andric   /// Note: This is not necessarily the address space of the string literal
8224ba319b5SDimitry Andric   /// in AST. For address space agnostic language, e.g. C++, string literal
8234ba319b5SDimitry Andric   /// in AST is always in default address space.
8244ba319b5SDimitry Andric   LangAS getStringLiteralAddressSpace() const;
8254ba319b5SDimitry Andric 
82659d1ed5bSDimitry Andric   /// Return the address of the given function. If Ty is non-null, then this
82759d1ed5bSDimitry Andric   /// function will use the specified type if it has to create it.
8280623d748SDimitry Andric   llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = nullptr,
82959d1ed5bSDimitry Andric                                     bool ForVTable = false,
8300623d748SDimitry Andric                                     bool DontDefer = false,
83144290647SDimitry Andric                                     ForDefinition_t IsForDefinition
83244290647SDimitry Andric                                       = NotForDefinition);
8333b0f4066SDimitry Andric 
83459d1ed5bSDimitry Andric   /// Get the address of the RTTI descriptor for the given type.
835f22ef01cSRoman Divacky   llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false);
836f22ef01cSRoman Divacky 
83759d1ed5bSDimitry Andric   /// Get the address of a uuid descriptor .
8380623d748SDimitry Andric   ConstantAddress GetAddrOfUuidDescriptor(const CXXUuidofExpr* E);
8393861d79fSDimitry Andric 
84059d1ed5bSDimitry Andric   /// Get the address of the thunk for the given global decl.
8414ba319b5SDimitry Andric   llvm::Constant *GetAddrOfThunk(StringRef Name, llvm::Type *FnTy,
8424ba319b5SDimitry Andric                                  GlobalDecl GD);
843f22ef01cSRoman Divacky 
84459d1ed5bSDimitry Andric   /// Get a reference to the target of VD.
8450623d748SDimitry Andric   ConstantAddress GetWeakRefReference(const ValueDecl *VD);
8460623d748SDimitry Andric 
8470623d748SDimitry Andric   /// Returns the assumed alignment of an opaque pointer to the given class.
8480623d748SDimitry Andric   CharUnits getClassPointerAlignment(const CXXRecordDecl *CD);
8490623d748SDimitry Andric 
8500623d748SDimitry Andric   /// Returns the assumed alignment of a virtual base of a class.
8510623d748SDimitry Andric   CharUnits getVBaseAlignment(CharUnits DerivedAlign,
8520623d748SDimitry Andric                               const CXXRecordDecl *Derived,
8530623d748SDimitry Andric                               const CXXRecordDecl *VBase);
8540623d748SDimitry Andric 
8550623d748SDimitry Andric   /// Given a class pointer with an actual known alignment, and the
8560623d748SDimitry Andric   /// expected alignment of an object at a dynamic offset w.r.t that
8570623d748SDimitry Andric   /// pointer, return the alignment to assume at the offset.
8580623d748SDimitry Andric   CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign,
8590623d748SDimitry Andric                                       const CXXRecordDecl *Class,
8600623d748SDimitry Andric                                       CharUnits ExpectedTargetAlign);
861f22ef01cSRoman Divacky 
8623dac3a9bSDimitry Andric   CharUnits
8633dac3a9bSDimitry Andric   computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass,
8643dac3a9bSDimitry Andric                                    CastExpr::path_const_iterator Start,
8653dac3a9bSDimitry Andric                                    CastExpr::path_const_iterator End);
8663dac3a9bSDimitry Andric 
86759d1ed5bSDimitry Andric   /// Returns the offset from a derived class to  a class. Returns null if the
86859d1ed5bSDimitry Andric   /// offset is 0.
869f22ef01cSRoman Divacky   llvm::Constant *
870f22ef01cSRoman Divacky   GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
871e580952dSDimitry Andric                                CastExpr::path_const_iterator PathBegin,
872e580952dSDimitry Andric                                CastExpr::path_const_iterator PathEnd);
873f22ef01cSRoman Divacky 
8740623d748SDimitry Andric   llvm::FoldingSet<BlockByrefHelpers> ByrefHelpersCache;
8752754fe60SDimitry Andric 
87659d1ed5bSDimitry Andric   /// Fetches the global unique block count.
getUniqueBlockCount()877dd6029ffSDimitry Andric   int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; }
8782754fe60SDimitry Andric 
87959d1ed5bSDimitry Andric   /// Fetches the type of a generic block descriptor.
88017a519f9SDimitry Andric   llvm::Type *getBlockDescriptorType();
8812754fe60SDimitry Andric 
88259d1ed5bSDimitry Andric   /// The type of a generic block literal.
88317a519f9SDimitry Andric   llvm::Type *getGenericBlockLiteralType();
8842754fe60SDimitry Andric 
88559d1ed5bSDimitry Andric   /// Gets the address of a block which requires no captures.
88644290647SDimitry Andric   llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name);
88744290647SDimitry Andric 
88844290647SDimitry Andric   /// Returns the address of a block which requires no caputres, or null if
88944290647SDimitry Andric   /// we've yet to emit the block for BE.
getAddrOfGlobalBlockIfEmitted(const BlockExpr * BE)89044290647SDimitry Andric   llvm::Constant *getAddrOfGlobalBlockIfEmitted(const BlockExpr *BE) {
89144290647SDimitry Andric     return EmittedGlobalBlocks.lookup(BE);
89244290647SDimitry Andric   }
89344290647SDimitry Andric 
89444290647SDimitry Andric   /// Notes that BE's global block is available via Addr. Asserts that BE
89544290647SDimitry Andric   /// isn't already emitted.
89644290647SDimitry Andric   void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr);
8972754fe60SDimitry Andric 
89859d1ed5bSDimitry Andric   /// Return a pointer to a constant CFString object for the given string.
8990623d748SDimitry Andric   ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal);
900f22ef01cSRoman Divacky 
90159d1ed5bSDimitry Andric   /// Return a pointer to a constant NSString object for the given string. Or a
90259d1ed5bSDimitry Andric   /// user defined String object as defined via
9032754fe60SDimitry Andric   /// -fconstant-string-class=class_name option.
9040623d748SDimitry Andric   ConstantAddress GetAddrOfConstantString(const StringLiteral *Literal);
905f22ef01cSRoman Divacky 
90659d1ed5bSDimitry Andric   /// Return a constant array for the given string.
907dff0c46cSDimitry Andric   llvm::Constant *GetConstantArrayFromStringLiteral(const StringLiteral *E);
908dff0c46cSDimitry Andric 
90959d1ed5bSDimitry Andric   /// Return a pointer to a constant array for the given string literal.
9100623d748SDimitry Andric   ConstantAddress
91139d628a0SDimitry Andric   GetAddrOfConstantStringFromLiteral(const StringLiteral *S,
91239d628a0SDimitry Andric                                      StringRef Name = ".str");
913f22ef01cSRoman Divacky 
91459d1ed5bSDimitry Andric   /// Return a pointer to a constant array for the given ObjCEncodeExpr node.
9150623d748SDimitry Andric   ConstantAddress
91659d1ed5bSDimitry Andric   GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *);
917f22ef01cSRoman Divacky 
91859d1ed5bSDimitry Andric   /// Returns a pointer to a character array containing the literal and a
91959d1ed5bSDimitry Andric   /// terminating '\0' character. The result has pointer to array type.
920f22ef01cSRoman Divacky   ///
921f22ef01cSRoman Divacky   /// \param GlobalName If provided, the name to use for the global (if one is
922f22ef01cSRoman Divacky   /// created).
9230623d748SDimitry Andric   ConstantAddress
92459d1ed5bSDimitry Andric   GetAddrOfConstantCString(const std::string &Str,
9250623d748SDimitry Andric                            const char *GlobalName = nullptr);
9266122f3e6SDimitry Andric 
92759d1ed5bSDimitry Andric   /// Returns a pointer to a constant global variable for the given file-scope
92859d1ed5bSDimitry Andric   /// compound literal expression.
9290623d748SDimitry Andric   ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E);
930dff0c46cSDimitry Andric 
93144290647SDimitry Andric   /// If it's been emitted already, returns the GlobalVariable corresponding to
93244290647SDimitry Andric   /// a compound literal. Otherwise, returns null.
93344290647SDimitry Andric   llvm::GlobalVariable *
93444290647SDimitry Andric   getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E);
93544290647SDimitry Andric 
93644290647SDimitry Andric   /// Notes that CLE's GlobalVariable is GV. Asserts that CLE isn't already
93744290647SDimitry Andric   /// emitted.
93844290647SDimitry Andric   void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE,
93944290647SDimitry Andric                                         llvm::GlobalVariable *GV);
94044290647SDimitry Andric 
9414ba319b5SDimitry Andric   /// Returns a pointer to a global variable representing a temporary
942f785676fSDimitry Andric   /// with static or thread storage duration.
9430623d748SDimitry Andric   ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E,
944f785676fSDimitry Andric                                            const Expr *Inner);
945f785676fSDimitry Andric 
9464ba319b5SDimitry Andric   /// Retrieve the record type that describes the state of an
9476122f3e6SDimitry Andric   /// Objective-C fast enumeration loop (for..in).
9486122f3e6SDimitry Andric   QualType getObjCFastEnumerationStateType();
949f22ef01cSRoman Divacky 
95039d628a0SDimitry Andric   // Produce code for this constructor/destructor. This method doesn't try
95139d628a0SDimitry Andric   // to apply any ABI rules about which other constructors/destructors
95239d628a0SDimitry Andric   // are needed or if they are alias to each other.
95339d628a0SDimitry Andric   llvm::Function *codegenCXXStructor(const CXXMethodDecl *MD,
95439d628a0SDimitry Andric                                      StructorType Type);
955f22ef01cSRoman Divacky 
95639d628a0SDimitry Andric   /// Return the address of the constructor/destructor of the given type.
9570623d748SDimitry Andric   llvm::Constant *
95839d628a0SDimitry Andric   getAddrOfCXXStructor(const CXXMethodDecl *MD, StructorType Type,
95939d628a0SDimitry Andric                        const CGFunctionInfo *FnInfo = nullptr,
96039d628a0SDimitry Andric                        llvm::FunctionType *FnType = nullptr,
96144290647SDimitry Andric                        bool DontDefer = false,
96244290647SDimitry Andric                        ForDefinition_t IsForDefinition = NotForDefinition);
963f22ef01cSRoman Divacky 
96459d1ed5bSDimitry Andric   /// Given a builtin id for a function like "__builtin_fabsf", return a
96559d1ed5bSDimitry Andric   /// Function* for "fabsf".
96644290647SDimitry Andric   llvm::Constant *getBuiltinLibFunction(const FunctionDecl *FD,
967f22ef01cSRoman Divacky                                         unsigned BuiltinID);
968f22ef01cSRoman Divacky 
969284c1978SDimitry Andric   llvm::Function *getIntrinsic(unsigned IID, ArrayRef<llvm::Type*> Tys = None);
970f22ef01cSRoman Divacky 
97159d1ed5bSDimitry Andric   /// Emit code for a single top level declaration.
972f22ef01cSRoman Divacky   void EmitTopLevelDecl(Decl *D);
973f22ef01cSRoman Divacky 
9744ba319b5SDimitry Andric   /// Stored a deferred empty coverage mapping for an unused
97539d628a0SDimitry Andric   /// and thus uninstrumented top level declaration.
97639d628a0SDimitry Andric   void AddDeferredUnusedCoverageMapping(Decl *D);
97739d628a0SDimitry Andric 
9784ba319b5SDimitry Andric   /// Remove the deferred empty coverage mapping as this
97939d628a0SDimitry Andric   /// declaration is actually instrumented.
98039d628a0SDimitry Andric   void ClearUnusedCoverageMapping(const Decl *D);
98139d628a0SDimitry Andric 
9824ba319b5SDimitry Andric   /// Emit all the deferred coverage mappings
98339d628a0SDimitry Andric   /// for the uninstrumented functions.
98439d628a0SDimitry Andric   void EmitDeferredUnusedCoverageMappings();
98539d628a0SDimitry Andric 
98659d1ed5bSDimitry Andric   /// Tell the consumer that this variable has been instantiated.
987dff0c46cSDimitry Andric   void HandleCXXStaticMemberVarInstantiation(VarDecl *VD);
988dff0c46cSDimitry Andric 
9894ba319b5SDimitry Andric   /// If the declaration has internal linkage but is inside an
990284c1978SDimitry Andric   /// extern "C" linkage specification, prepare to emit an alias for it
991284c1978SDimitry Andric   /// to the expected name.
992284c1978SDimitry Andric   template<typename SomeDecl>
993284c1978SDimitry Andric   void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV);
994284c1978SDimitry Andric 
99559d1ed5bSDimitry Andric   /// Add a global to a list to be added to the llvm.used metadata.
99659d1ed5bSDimitry Andric   void addUsedGlobal(llvm::GlobalValue *GV);
997f22ef01cSRoman Divacky 
99859d1ed5bSDimitry Andric   /// Add a global to a list to be added to the llvm.compiler.used metadata.
99959d1ed5bSDimitry Andric   void addCompilerUsedGlobal(llvm::GlobalValue *GV);
100059d1ed5bSDimitry Andric 
100159d1ed5bSDimitry Andric   /// Add a destructor and object to add to the C++ global destructor function.
AddCXXDtorEntry(llvm::Constant * DtorFn,llvm::Constant * Object)1002ffd1746dSEd Schouten   void AddCXXDtorEntry(llvm::Constant *DtorFn, llvm::Constant *Object) {
100397bc6c73SDimitry Andric     CXXGlobalDtors.emplace_back(DtorFn, Object);
1004ffd1746dSEd Schouten   }
1005f22ef01cSRoman Divacky 
100659d1ed5bSDimitry Andric   /// Create a new runtime function with the specified type and name.
100744290647SDimitry Andric   llvm::Constant *
100844290647SDimitry Andric   CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name,
100920e90f04SDimitry Andric                         llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
101044290647SDimitry Andric                         bool Local = false);
101144290647SDimitry Andric 
101239d628a0SDimitry Andric   /// Create a new compiler builtin function with the specified type and name.
101320e90f04SDimitry Andric   llvm::Constant *
101420e90f04SDimitry Andric   CreateBuiltinFunction(llvm::FunctionType *Ty, StringRef Name,
101520e90f04SDimitry Andric                         llvm::AttributeList ExtraAttrs = llvm::AttributeList());
101659d1ed5bSDimitry Andric   /// Create a new runtime global variable with the specified type and name.
10176122f3e6SDimitry Andric   llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty,
10186122f3e6SDimitry Andric                                         StringRef Name);
1019f22ef01cSRoman Divacky 
1020e580952dSDimitry Andric   ///@name Custom Blocks Runtime Interfaces
1021e580952dSDimitry Andric   ///@{
1022e580952dSDimitry Andric 
1023e580952dSDimitry Andric   llvm::Constant *getNSConcreteGlobalBlock();
1024e580952dSDimitry Andric   llvm::Constant *getNSConcreteStackBlock();
1025e580952dSDimitry Andric   llvm::Constant *getBlockObjectAssign();
1026e580952dSDimitry Andric   llvm::Constant *getBlockObjectDispose();
1027e580952dSDimitry Andric 
1028e580952dSDimitry Andric   ///@}
1029e580952dSDimitry Andric 
1030139f7f9bSDimitry Andric   llvm::Constant *getLLVMLifetimeStartFn();
1031139f7f9bSDimitry Andric   llvm::Constant *getLLVMLifetimeEndFn();
1032139f7f9bSDimitry Andric 
103359d1ed5bSDimitry Andric   // Make sure that this type is translated.
10343b0f4066SDimitry Andric   void UpdateCompletedType(const TagDecl *TD);
1035f22ef01cSRoman Divacky 
10362754fe60SDimitry Andric   llvm::Constant *getMemberPointerConstant(const UnaryOperator *e);
10372754fe60SDimitry Andric 
10384ba319b5SDimitry Andric   /// Emit type info if type of an expression is a variably modified
10390623d748SDimitry Andric   /// type. Also emit proper debug info for cast types.
10400623d748SDimitry Andric   void EmitExplicitCastExprType(const ExplicitCastExpr *E,
10410623d748SDimitry Andric                                 CodeGenFunction *CGF = nullptr);
10420623d748SDimitry Andric 
104359d1ed5bSDimitry Andric   /// Return the result of value-initializing the given type, i.e. a null
104459d1ed5bSDimitry Andric   /// expression of the given type.  This is usually, but not always, an LLVM
104559d1ed5bSDimitry Andric   /// null constant.
1046f22ef01cSRoman Divacky   llvm::Constant *EmitNullConstant(QualType T);
1047f22ef01cSRoman Divacky 
104859d1ed5bSDimitry Andric   /// Return a null constant appropriate for zero-initializing a base class with
104959d1ed5bSDimitry Andric   /// the given type. This is usually, but not always, an LLVM null constant.
10506122f3e6SDimitry Andric   llvm::Constant *EmitNullConstantForBase(const CXXRecordDecl *Record);
1051f22ef01cSRoman Divacky 
105259d1ed5bSDimitry Andric   /// Emit a general error that something can't be done.
10536122f3e6SDimitry Andric   void Error(SourceLocation loc, StringRef error);
10543b0f4066SDimitry Andric 
105559d1ed5bSDimitry Andric   /// Print out an error that codegen doesn't support the specified stmt yet.
1056f785676fSDimitry Andric   void ErrorUnsupported(const Stmt *S, const char *Type);
1057f22ef01cSRoman Divacky 
105859d1ed5bSDimitry Andric   /// Print out an error that codegen doesn't support the specified decl yet.
1059f785676fSDimitry Andric   void ErrorUnsupported(const Decl *D, const char *Type);
1060f22ef01cSRoman Divacky 
106159d1ed5bSDimitry Andric   /// Set the attributes on the LLVM function for the given decl and function
106259d1ed5bSDimitry Andric   /// info. This applies attributes necessary for handling the ABI as well as
106359d1ed5bSDimitry Andric   /// user specified attributes like section.
10644ba319b5SDimitry Andric   void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F,
1065f22ef01cSRoman Divacky                                      const CGFunctionInfo &FI);
1066f22ef01cSRoman Divacky 
106759d1ed5bSDimitry Andric   /// Set the LLVM function attributes (sext, zext, etc).
1068*b5893f02SDimitry Andric   void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info,
1069f22ef01cSRoman Divacky                                  llvm::Function *F);
1070f22ef01cSRoman Divacky 
107159d1ed5bSDimitry Andric   /// Set the LLVM function attributes which only apply to a function
107239d628a0SDimitry Andric   /// definition.
1073f22ef01cSRoman Divacky   void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F);
1074f22ef01cSRoman Divacky 
107559d1ed5bSDimitry Andric   /// Return true iff the given type uses 'sret' when used as a return type.
1076ffd1746dSEd Schouten   bool ReturnTypeUsesSRet(const CGFunctionInfo &FI);
1077ffd1746dSEd Schouten 
107859d1ed5bSDimitry Andric   /// Return true iff the given type uses an argument slot when 'sret' is used
107959d1ed5bSDimitry Andric   /// as a return type.
108059d1ed5bSDimitry Andric   bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI);
108159d1ed5bSDimitry Andric 
108259d1ed5bSDimitry Andric   /// Return true iff the given type uses 'fpret' when used as a return type.
1083ffd1746dSEd Schouten   bool ReturnTypeUsesFPRet(QualType ResultType);
1084f22ef01cSRoman Divacky 
108559d1ed5bSDimitry Andric   /// Return true iff the given type uses 'fp2ret' when used as a return type.
1086dff0c46cSDimitry Andric   bool ReturnTypeUsesFP2Ret(QualType ResultType);
1087dff0c46cSDimitry Andric 
108859d1ed5bSDimitry Andric   /// Get the LLVM attributes and calling convention to use for a particular
108959d1ed5bSDimitry Andric   /// function type.
1090f22ef01cSRoman Divacky   ///
1091ea942507SDimitry Andric   /// \param Name - The function name.
1092f22ef01cSRoman Divacky   /// \param Info - The function type information.
10930623d748SDimitry Andric   /// \param CalleeInfo - The callee information these attributes are being
10940623d748SDimitry Andric   /// constructed for. If valid, the attributes applied to this decl may
10950623d748SDimitry Andric   /// contribute to the function attributes and calling convention.
10966bc11b14SDimitry Andric   /// \param Attrs [out] - On return, the attribute list to use.
1097f22ef01cSRoman Divacky   /// \param CallingConv [out] - On return, the LLVM calling convention to use.
1098ea942507SDimitry Andric   void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info,
10996bc11b14SDimitry Andric                               CGCalleeInfo CalleeInfo,
11006bc11b14SDimitry Andric                               llvm::AttributeList &Attrs, unsigned &CallingConv,
11016bc11b14SDimitry Andric                               bool AttrOnCallSite);
11020623d748SDimitry Andric 
110320e90f04SDimitry Andric   /// Adds attributes to F according to our CodeGenOptions and LangOptions, as
110420e90f04SDimitry Andric   /// though we had emitted it ourselves.  We remove any attributes on F that
110520e90f04SDimitry Andric   /// conflict with the attributes we add here.
110620e90f04SDimitry Andric   ///
110720e90f04SDimitry Andric   /// This is useful for adding attrs to bitcode modules that you want to link
110820e90f04SDimitry Andric   /// with but don't control, such as CUDA's libdevice.  When linking with such
110920e90f04SDimitry Andric   /// a bitcode library, you might want to set e.g. its functions'
111020e90f04SDimitry Andric   /// "unsafe-fp-math" attribute to match the attr of the functions you're
111120e90f04SDimitry Andric   /// codegen'ing.  Otherwise, LLVM will interpret the bitcode module's lack of
111220e90f04SDimitry Andric   /// unsafe-fp-math attrs as tantamount to unsafe-fp-math=false, and then LLVM
111320e90f04SDimitry Andric   /// will propagate unsafe-fp-math=false up to every transitive caller of a
111420e90f04SDimitry Andric   /// function in the bitcode library!
111520e90f04SDimitry Andric   ///
111620e90f04SDimitry Andric   /// With the exception of fast-math attrs, this will only make the attributes
111720e90f04SDimitry Andric   /// on the function more conservative.  But it's unsafe to call this on a
111820e90f04SDimitry Andric   /// function which relies on particular fast-math attributes for correctness.
111920e90f04SDimitry Andric   /// It's up to you to ensure that this is safe.
112020e90f04SDimitry Andric   void AddDefaultFnAttrs(llvm::Function &F);
112120e90f04SDimitry Andric 
11224ba319b5SDimitry Andric   /// Parses the target attributes passed in, and returns only the ones that are
11234ba319b5SDimitry Andric   /// valid feature names.
11244ba319b5SDimitry Andric   TargetAttr::ParsedTargetAttr filterFunctionTargetAttrs(const TargetAttr *TD);
11254ba319b5SDimitry Andric 
11260623d748SDimitry Andric   // Fills in the supplied string map with the set of target features for the
11270623d748SDimitry Andric   // passed in function.
1128*b5893f02SDimitry Andric   void getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap, GlobalDecl GD);
1129f22ef01cSRoman Divacky 
11306122f3e6SDimitry Andric   StringRef getMangledName(GlobalDecl GD);
113159d1ed5bSDimitry Andric   StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD);
1132f22ef01cSRoman Divacky 
1133f22ef01cSRoman Divacky   void EmitTentativeDefinition(const VarDecl *D);
1134f22ef01cSRoman Divacky 
113533956c43SDimitry Andric   void EmitVTable(CXXRecordDecl *Class);
1136f22ef01cSRoman Divacky 
1137e7145dcbSDimitry Andric   void RefreshTypeCacheForClass(const CXXRecordDecl *Class);
1138e7145dcbSDimitry Andric 
11394ba319b5SDimitry Andric   /// Appends Opts to the "llvm.linker.options" metadata value.
1140f785676fSDimitry Andric   void AppendLinkerOptions(StringRef Opts);
1141f785676fSDimitry Andric 
11424ba319b5SDimitry Andric   /// Appends a detect mismatch command to the linker options.
1143f785676fSDimitry Andric   void AddDetectMismatch(StringRef Name, StringRef Value);
1144f785676fSDimitry Andric 
11454ba319b5SDimitry Andric   /// Appends a dependent lib to the "llvm.linker.options" metadata
114624d58133SDimitry Andric   /// value.
1147f785676fSDimitry Andric   void AddDependentLib(StringRef Lib);
1148f785676fSDimitry Andric 
11494ba319b5SDimitry Andric   void AddELFLibDirective(StringRef Lib);
11504ba319b5SDimitry Andric 
1151f785676fSDimitry Andric   llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD);
1152f785676fSDimitry Andric 
setFunctionLinkage(GlobalDecl GD,llvm::Function * F)115359d1ed5bSDimitry Andric   void setFunctionLinkage(GlobalDecl GD, llvm::Function *F) {
115459d1ed5bSDimitry Andric     F->setLinkage(getFunctionLinkage(GD));
1155f22ef01cSRoman Divacky   }
1156f22ef01cSRoman Divacky 
115759d1ed5bSDimitry Andric   /// Return the appropriate linkage for the vtable, VTT, and type information
115859d1ed5bSDimitry Andric   /// of the given class.
11592754fe60SDimitry Andric   llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD);
1160f22ef01cSRoman Divacky 
116159d1ed5bSDimitry Andric   /// Return the store size, in character units, of the given LLVM type.
11626122f3e6SDimitry Andric   CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const;
1163f22ef01cSRoman Divacky 
116459d1ed5bSDimitry Andric   /// Returns LLVM linkage for a declarator.
11652754fe60SDimitry Andric   llvm::GlobalValue::LinkageTypes
116659d1ed5bSDimitry Andric   getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage,
116759d1ed5bSDimitry Andric                               bool IsConstantVariable);
116859d1ed5bSDimitry Andric 
116959d1ed5bSDimitry Andric   /// Returns LLVM linkage for a declarator.
117059d1ed5bSDimitry Andric   llvm::GlobalValue::LinkageTypes
117159d1ed5bSDimitry Andric   getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant);
11722754fe60SDimitry Andric 
11736122f3e6SDimitry Andric   /// Emit all the global annotations.
11746122f3e6SDimitry Andric   void EmitGlobalAnnotations();
1175f22ef01cSRoman Divacky 
11766122f3e6SDimitry Andric   /// Emit an annotation string.
1177139f7f9bSDimitry Andric   llvm::Constant *EmitAnnotationString(StringRef Str);
11786122f3e6SDimitry Andric 
11796122f3e6SDimitry Andric   /// Emit the annotation's translation unit.
11806122f3e6SDimitry Andric   llvm::Constant *EmitAnnotationUnit(SourceLocation Loc);
11816122f3e6SDimitry Andric 
11826122f3e6SDimitry Andric   /// Emit the annotation line number.
11836122f3e6SDimitry Andric   llvm::Constant *EmitAnnotationLineNo(SourceLocation L);
11846122f3e6SDimitry Andric 
118559d1ed5bSDimitry Andric   /// Generate the llvm::ConstantStruct which contains the annotation
118659d1ed5bSDimitry Andric   /// information for a given GlobalValue. The annotation struct is
11876122f3e6SDimitry Andric   /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the
11886122f3e6SDimitry Andric   /// GlobalValue being annotated. The second field is the constant string
11896122f3e6SDimitry Andric   /// created from the AnnotateAttr's annotation. The third field is a constant
11906122f3e6SDimitry Andric   /// string containing the name of the translation unit. The fourth field is
11916122f3e6SDimitry Andric   /// the line number in the file of the annotated value declaration.
11926122f3e6SDimitry Andric   llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
11936122f3e6SDimitry Andric                                    const AnnotateAttr *AA,
11946122f3e6SDimitry Andric                                    SourceLocation L);
11956122f3e6SDimitry Andric 
11966122f3e6SDimitry Andric   /// Add global annotations that are set on D, for the global GV. Those
11976122f3e6SDimitry Andric   /// annotations are emitted during finalization of the LLVM code.
11986122f3e6SDimitry Andric   void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
11996122f3e6SDimitry Andric 
12009a199699SDimitry Andric   bool isInSanitizerBlacklist(SanitizerMask Kind, llvm::Function *Fn,
12019a199699SDimitry Andric                               SourceLocation Loc) const;
120239d628a0SDimitry Andric 
120339d628a0SDimitry Andric   bool isInSanitizerBlacklist(llvm::GlobalVariable *GV, SourceLocation Loc,
120439d628a0SDimitry Andric                               QualType Ty,
120539d628a0SDimitry Andric                               StringRef Category = StringRef()) const;
120639d628a0SDimitry Andric 
120720e90f04SDimitry Andric   /// Imbue XRay attributes to a function, applying the always/never attribute
120820e90f04SDimitry Andric   /// lists in the process. Returns true if we did imbue attributes this way,
120920e90f04SDimitry Andric   /// false otherwise.
121020e90f04SDimitry Andric   bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc,
121120e90f04SDimitry Andric                       StringRef Category = StringRef()) const;
121220e90f04SDimitry Andric 
getSanitizerMetadata()121339d628a0SDimitry Andric   SanitizerMetadata *getSanitizerMetadata() {
121439d628a0SDimitry Andric     return SanitizerMD.get();
1215139f7f9bSDimitry Andric   }
1216139f7f9bSDimitry Andric 
addDeferredVTable(const CXXRecordDecl * RD)1217139f7f9bSDimitry Andric   void addDeferredVTable(const CXXRecordDecl *RD) {
1218139f7f9bSDimitry Andric     DeferredVTables.push_back(RD);
1219139f7f9bSDimitry Andric   }
1220139f7f9bSDimitry Andric 
12214ba319b5SDimitry Andric   /// Emit code for a single global function or var decl. Forward declarations
122259d1ed5bSDimitry Andric   /// are emitted lazily.
1223f785676fSDimitry Andric   void EmitGlobal(GlobalDecl D);
1224f785676fSDimitry Andric 
122539d628a0SDimitry Andric   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
122639d628a0SDimitry Andric 
12276122f3e6SDimitry Andric   llvm::GlobalValue *GetGlobalValue(StringRef Ref);
12286122f3e6SDimitry Andric 
122959d1ed5bSDimitry Andric   /// Set attributes which are common to any form of a global definition (alias,
123059d1ed5bSDimitry Andric   /// Objective-C method, function, global variable).
1231f22ef01cSRoman Divacky   ///
1232f22ef01cSRoman Divacky   /// NOTE: This should only be called for definitions.
12334ba319b5SDimitry Andric   void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV);
123439d628a0SDimitry Andric 
123539d628a0SDimitry Andric   void addReplacement(StringRef Name, llvm::Constant *C);
123639d628a0SDimitry Andric 
12370623d748SDimitry Andric   void addGlobalValReplacement(llvm::GlobalValue *GV, llvm::Constant *C);
12380623d748SDimitry Andric 
12394ba319b5SDimitry Andric   /// Emit a code for threadprivate directive.
124039d628a0SDimitry Andric   /// \param D Threadprivate declaration.
124139d628a0SDimitry Andric   void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
124239d628a0SDimitry Andric 
12434ba319b5SDimitry Andric   /// Emit a code for declare reduction construct.
1244e7145dcbSDimitry Andric   void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
1245e7145dcbSDimitry Andric                                CodeGenFunction *CGF = nullptr);
1246875ed548SDimitry Andric 
1247*b5893f02SDimitry Andric   /// Emit a code for requires directive.
1248*b5893f02SDimitry Andric   /// \param D Requires declaration
1249*b5893f02SDimitry Andric   void EmitOMPRequiresDecl(const OMPRequiresDecl *D);
1250*b5893f02SDimitry Andric 
1251e7145dcbSDimitry Andric   /// Returns whether the given record has hidden LTO visibility and therefore
1252e7145dcbSDimitry Andric   /// may participate in (single-module) CFI and whole-program vtable
1253e7145dcbSDimitry Andric   /// optimization.
1254e7145dcbSDimitry Andric   bool HasHiddenLTOVisibility(const CXXRecordDecl *RD);
1255e7145dcbSDimitry Andric 
1256e7145dcbSDimitry Andric   /// Emit type metadata for the given vtable using the given layout.
1257e7145dcbSDimitry Andric   void EmitVTableTypeMetadata(llvm::GlobalVariable *VTable,
125833956c43SDimitry Andric                               const VTableLayout &VTLayout);
125933956c43SDimitry Andric 
1260e7145dcbSDimitry Andric   /// Generate a cross-DSO type identifier for MD.
1261e7145dcbSDimitry Andric   llvm::ConstantInt *CreateCrossDsoCfiTypeId(llvm::Metadata *MD);
12620623d748SDimitry Andric 
12630623d748SDimitry Andric   /// Create a metadata identifier for the given type. This may either be an
12640623d748SDimitry Andric   /// MDString (for external identifiers) or a distinct unnamed MDNode (for
12650623d748SDimitry Andric   /// internal identifiers).
12660623d748SDimitry Andric   llvm::Metadata *CreateMetadataIdentifierForType(QualType T);
12670623d748SDimitry Andric 
12684ba319b5SDimitry Andric   /// Create a metadata identifier that is intended to be used to check virtual
12694ba319b5SDimitry Andric   /// calls via a member function pointer.
12704ba319b5SDimitry Andric   llvm::Metadata *CreateMetadataIdentifierForVirtualMemPtrType(QualType T);
12714ba319b5SDimitry Andric 
12729a199699SDimitry Andric   /// Create a metadata identifier for the generalization of the given type.
12739a199699SDimitry Andric   /// This may either be an MDString (for external identifiers) or a distinct
12749a199699SDimitry Andric   /// unnamed MDNode (for internal identifiers).
12759a199699SDimitry Andric   llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T);
12769a199699SDimitry Andric 
1277e7145dcbSDimitry Andric   /// Create and attach type metadata to the given function.
12784ba319b5SDimitry Andric   void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
12794ba319b5SDimitry Andric                                           llvm::Function *F);
12800623d748SDimitry Andric 
1281e7145dcbSDimitry Andric   /// Returns whether this module needs the "all-vtables" type identifier.
1282e7145dcbSDimitry Andric   bool NeedAllVtablesTypeId() const;
1283e7145dcbSDimitry Andric 
1284e7145dcbSDimitry Andric   /// Create and attach type metadata for the given vtable.
1285e7145dcbSDimitry Andric   void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset,
12868f0fd8f6SDimitry Andric                              const CXXRecordDecl *RD);
12878f0fd8f6SDimitry Andric 
12884ba319b5SDimitry Andric   /// Return a vector of most-base classes for RD. This is used to implement
12894ba319b5SDimitry Andric   /// control flow integrity checks for member function pointers.
12904ba319b5SDimitry Andric   ///
12914ba319b5SDimitry Andric   /// A most-base class of a class C is defined as a recursive base class of C,
12924ba319b5SDimitry Andric   /// including C itself, that does not have any bases.
12934ba319b5SDimitry Andric   std::vector<const CXXRecordDecl *>
12944ba319b5SDimitry Andric   getMostBaseClasses(const CXXRecordDecl *RD);
12954ba319b5SDimitry Andric 
12964ba319b5SDimitry Andric   /// Get the declaration of std::terminate for the platform.
129733956c43SDimitry Andric   llvm::Constant *getTerminateFn();
129833956c43SDimitry Andric 
1299e7145dcbSDimitry Andric   llvm::SanitizerStatReport &getSanStats();
1300e7145dcbSDimitry Andric 
130144290647SDimitry Andric   llvm::Value *
130244290647SDimitry Andric   createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF);
130344290647SDimitry Andric 
130444290647SDimitry Andric   /// Get target specific null pointer.
130544290647SDimitry Andric   /// \param T is the LLVM type of the null pointer.
130644290647SDimitry Andric   /// \param QT is the clang QualType of the null pointer.
130744290647SDimitry Andric   llvm::Constant *getNullPointer(llvm::PointerType *T, QualType QT);
130844290647SDimitry Andric 
130939d628a0SDimitry Andric private:
131020e90f04SDimitry Andric   llvm::Constant *GetOrCreateLLVMFunction(
131120e90f04SDimitry Andric       StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable,
131220e90f04SDimitry Andric       bool DontDefer = false, bool IsThunk = false,
131320e90f04SDimitry Andric       llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
131444290647SDimitry Andric       ForDefinition_t IsForDefinition = NotForDefinition);
131539d628a0SDimitry Andric 
1316*b5893f02SDimitry Andric   llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD,
13174ba319b5SDimitry Andric                                                   llvm::Type *DeclTy,
13184ba319b5SDimitry Andric                                                   const FunctionDecl *FD);
13194ba319b5SDimitry Andric   void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD);
13204ba319b5SDimitry Andric 
132139d628a0SDimitry Andric   llvm::Constant *GetOrCreateLLVMGlobal(StringRef MangledName,
132239d628a0SDimitry Andric                                         llvm::PointerType *PTy,
1323e7145dcbSDimitry Andric                                         const VarDecl *D,
132444290647SDimitry Andric                                         ForDefinition_t IsForDefinition
132544290647SDimitry Andric                                           = NotForDefinition);
132639d628a0SDimitry Andric 
1327*b5893f02SDimitry Andric   bool GetCPUAndFeaturesAttributes(GlobalDecl GD,
13284ba319b5SDimitry Andric                                    llvm::AttrBuilder &AttrBuilder);
13294ba319b5SDimitry Andric   void setNonAliasAttributes(GlobalDecl GD, llvm::GlobalObject *GO);
1330f22ef01cSRoman Divacky 
133159d1ed5bSDimitry Andric   /// Set function attributes for a function declaration.
133239d628a0SDimitry Andric   void SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
13334ba319b5SDimitry Andric                              bool IsIncompleteFunction, bool IsThunk);
1334f22ef01cSRoman Divacky 
133559d1ed5bSDimitry Andric   void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr);
1336f22ef01cSRoman Divacky 
133759d1ed5bSDimitry Andric   void EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV);
1338*b5893f02SDimitry Andric   void EmitMultiVersionFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV);
1339*b5893f02SDimitry Andric 
1340e7145dcbSDimitry Andric   void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false);
1341f22ef01cSRoman Divacky   void EmitAliasDefinition(GlobalDecl GD);
1342e7145dcbSDimitry Andric   void emitIFuncDefinition(GlobalDecl GD);
13434ba319b5SDimitry Andric   void emitCPUDispatchDefinition(GlobalDecl GD);
1344f22ef01cSRoman Divacky   void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
1345f22ef01cSRoman Divacky   void EmitObjCIvarInitializations(ObjCImplementationDecl *D);
1346f22ef01cSRoman Divacky 
1347f22ef01cSRoman Divacky   // C++ related functions.
1348f22ef01cSRoman Divacky 
134944290647SDimitry Andric   void EmitDeclContext(const DeclContext *DC);
1350f22ef01cSRoman Divacky   void EmitLinkageSpec(const LinkageSpecDecl *D);
1351f22ef01cSRoman Divacky 
13524ba319b5SDimitry Andric   /// Emit the function that initializes C++ thread_local variables.
1353284c1978SDimitry Andric   void EmitCXXThreadLocalInitFunc();
1354284c1978SDimitry Andric 
135559d1ed5bSDimitry Andric   /// Emit the function that initializes C++ globals.
1356f22ef01cSRoman Divacky   void EmitCXXGlobalInitFunc();
1357f22ef01cSRoman Divacky 
135859d1ed5bSDimitry Andric   /// Emit the function that destroys C++ globals.
1359f22ef01cSRoman Divacky   void EmitCXXGlobalDtorFunc();
1360f22ef01cSRoman Divacky 
136159d1ed5bSDimitry Andric   /// Emit the function that initializes the specified global (if PerformInit is
136259d1ed5bSDimitry Andric   /// true) and registers its destructor.
13632754fe60SDimitry Andric   void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
1364dff0c46cSDimitry Andric                                     llvm::GlobalVariable *Addr,
1365dff0c46cSDimitry Andric                                     bool PerformInit);
1366f22ef01cSRoman Divacky 
136759d1ed5bSDimitry Andric   void EmitPointerToInitFunc(const VarDecl *VD, llvm::GlobalVariable *Addr,
136859d1ed5bSDimitry Andric                              llvm::Function *InitFunc, InitSegAttr *ISA);
136959d1ed5bSDimitry Andric 
1370f22ef01cSRoman Divacky   // FIXME: Hardcoding priority here is gross.
137159d1ed5bSDimitry Andric   void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535,
13720623d748SDimitry Andric                      llvm::Constant *AssociatedData = nullptr);
1373f22ef01cSRoman Divacky   void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535);
1374f22ef01cSRoman Divacky 
137544290647SDimitry Andric   /// EmitCtorList - Generates a global array of functions and priorities using
137644290647SDimitry Andric   /// the given list and name. This array will have appending linkage and is
137744290647SDimitry Andric   /// suitable for use as a LLVM constructor or destructor array. Clears Fns.
137844290647SDimitry Andric   void EmitCtorList(CtorList &Fns, const char *GlobalName);
1379f22ef01cSRoman Divacky 
138059d1ed5bSDimitry Andric   /// Emit any needed decls for which code generation was deferred.
1381139f7f9bSDimitry Andric   void EmitDeferred();
1382139f7f9bSDimitry Andric 
1383f9448bf3SDimitry Andric   /// Try to emit external vtables as available_externally if they have emitted
1384f9448bf3SDimitry Andric   /// all inlined virtual functions.  It runs after EmitDeferred() and therefore
1385f9448bf3SDimitry Andric   /// is not allowed to create new references to things that need to be emitted
1386f9448bf3SDimitry Andric   /// lazily.
1387f9448bf3SDimitry Andric   void EmitVTablesOpportunistically();
1388f9448bf3SDimitry Andric 
1389f785676fSDimitry Andric   /// Call replaceAllUsesWith on all pairs in Replacements.
1390f785676fSDimitry Andric   void applyReplacements();
1391f785676fSDimitry Andric 
13920623d748SDimitry Andric   /// Call replaceAllUsesWith on all pairs in GlobalValReplacements.
13930623d748SDimitry Andric   void applyGlobalValReplacements();
13940623d748SDimitry Andric 
1395f785676fSDimitry Andric   void checkAliases();
1396f785676fSDimitry Andric 
13974ba319b5SDimitry Andric   std::map<int, llvm::TinyPtrVector<llvm::Function *>> DtorsUsingAtExit;
13984ba319b5SDimitry Andric 
13994ba319b5SDimitry Andric   /// Register functions annotated with __attribute__((destructor)) using
14004ba319b5SDimitry Andric   /// __cxa_atexit, if it is available, or atexit otherwise.
14014ba319b5SDimitry Andric   void registerGlobalDtorsWithAtExit();
14024ba319b5SDimitry Andric 
14034ba319b5SDimitry Andric   void emitMultiVersionFunctions();
14044ba319b5SDimitry Andric 
140559d1ed5bSDimitry Andric   /// Emit any vtables which we deferred and still have a use for.
1406139f7f9bSDimitry Andric   void EmitDeferredVTables();
1407f22ef01cSRoman Divacky 
140820e90f04SDimitry Andric   /// Emit a dummy function that reference a CoreFoundation symbol when
140920e90f04SDimitry Andric   /// @available is used on Darwin.
141020e90f04SDimitry Andric   void emitAtAvailableLinkGuard();
141120e90f04SDimitry Andric 
141259d1ed5bSDimitry Andric   /// Emit the llvm.used and llvm.compiler.used metadata.
141359d1ed5bSDimitry Andric   void emitLLVMUsed();
1414139f7f9bSDimitry Andric 
14154ba319b5SDimitry Andric   /// Emit the link options introduced by imported modules.
1416139f7f9bSDimitry Andric   void EmitModuleLinkOptions();
1417f22ef01cSRoman Divacky 
14184ba319b5SDimitry Andric   /// Emit aliases for internal-linkage declarations inside "C" language
1419284c1978SDimitry Andric   /// linkage specifications, giving them the "expected" name where possible.
1420284c1978SDimitry Andric   void EmitStaticExternCAliases();
1421284c1978SDimitry Andric 
1422ffd1746dSEd Schouten   void EmitDeclMetadata();
1423ffd1746dSEd Schouten 
14244ba319b5SDimitry Andric   /// Emit the Clang version as llvm.ident metadata.
1425f785676fSDimitry Andric   void EmitVersionIdentMetadata();
1426f785676fSDimitry Andric 
1427*b5893f02SDimitry Andric   /// Emit the Clang commandline as llvm.commandline metadata.
1428*b5893f02SDimitry Andric   void EmitCommandLineMetadata();
1429*b5893f02SDimitry Andric 
143059d1ed5bSDimitry Andric   /// Emits target specific Metadata for global declarations.
143159d1ed5bSDimitry Andric   void EmitTargetMetadata();
143259d1ed5bSDimitry Andric 
1433edd7eaddSDimitry Andric   /// Emits OpenCL specific Metadata e.g. OpenCL version.
1434edd7eaddSDimitry Andric   void EmitOpenCLMetadata();
1435edd7eaddSDimitry Andric 
143659d1ed5bSDimitry Andric   /// Emit the llvm.gcov metadata used to tell LLVM where to emit the .gcno and
143759d1ed5bSDimitry Andric   /// .gcda files in a way that persists in .bc files.
1438bd5abe19SDimitry Andric   void EmitCoverageFile();
1439bd5abe19SDimitry Andric 
14403861d79fSDimitry Andric   /// Emits the initializer for a uuidof string.
144139d628a0SDimitry Andric   llvm::Constant *EmitUuidofInitializer(StringRef uuidstr);
14423861d79fSDimitry Andric 
144339d628a0SDimitry Andric   /// Determine whether the definition must be emitted; if this returns \c
144439d628a0SDimitry Andric   /// false, the definition can be emitted lazily if it's used.
144539d628a0SDimitry Andric   bool MustBeEmitted(const ValueDecl *D);
144639d628a0SDimitry Andric 
144739d628a0SDimitry Andric   /// Determine whether the definition can be emitted eagerly, or should be
144839d628a0SDimitry Andric   /// delayed until the end of the translation unit. This is relevant for
144939d628a0SDimitry Andric   /// definitions whose linkage can change, e.g. implicit function instantions
145039d628a0SDimitry Andric   /// which may later be explicitly instantiated.
145139d628a0SDimitry Andric   bool MayBeEmittedEagerly(const ValueDecl *D);
14522754fe60SDimitry Andric 
145359d1ed5bSDimitry Andric   /// Check whether we can use a "simpler", more core exceptions personality
145459d1ed5bSDimitry Andric   /// function.
14552754fe60SDimitry Andric   void SimplifyPersonality();
145620e90f04SDimitry Andric 
145720e90f04SDimitry Andric   /// Helper function for ConstructAttributeList and AddDefaultFnAttrs.
145820e90f04SDimitry Andric   /// Constructs an AttrList for a function with the given properties.
145920e90f04SDimitry Andric   void ConstructDefaultFnAttrList(StringRef Name, bool HasOptnone,
146020e90f04SDimitry Andric                                   bool AttrOnCallSite,
146120e90f04SDimitry Andric                                   llvm::AttrBuilder &FuncAttrs);
14624ba319b5SDimitry Andric 
14634ba319b5SDimitry Andric   llvm::Metadata *CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map,
14644ba319b5SDimitry Andric                                                StringRef Suffix);
1465f22ef01cSRoman Divacky };
14669a199699SDimitry Andric 
1467f22ef01cSRoman Divacky }  // end namespace CodeGen
1468f22ef01cSRoman Divacky }  // end namespace clang
1469f22ef01cSRoman Divacky 
14700623d748SDimitry Andric #endif // LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H
1471