xref: /openbsd-src/gnu/llvm/clang/lib/CodeGen/CodeGenModule.h (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- CodeGenModule.h - Per-Module state for LLVM CodeGen ----*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This is the internal per-translation-unit state used for llvm translation.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H
14e5dd7070Spatrick #define LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H
15e5dd7070Spatrick 
16e5dd7070Spatrick #include "CGVTables.h"
17e5dd7070Spatrick #include "CodeGenTypeCache.h"
18e5dd7070Spatrick #include "CodeGenTypes.h"
19e5dd7070Spatrick #include "SanitizerMetadata.h"
20e5dd7070Spatrick #include "clang/AST/DeclCXX.h"
21e5dd7070Spatrick #include "clang/AST/DeclObjC.h"
22e5dd7070Spatrick #include "clang/AST/DeclOpenMP.h"
23e5dd7070Spatrick #include "clang/AST/GlobalDecl.h"
24e5dd7070Spatrick #include "clang/AST/Mangle.h"
25e5dd7070Spatrick #include "clang/Basic/ABI.h"
26e5dd7070Spatrick #include "clang/Basic/LangOptions.h"
27e5dd7070Spatrick #include "clang/Basic/Module.h"
28a9ac8606Spatrick #include "clang/Basic/NoSanitizeList.h"
29ec727ea7Spatrick #include "clang/Basic/TargetInfo.h"
30e5dd7070Spatrick #include "clang/Basic/XRayLists.h"
31a9ac8606Spatrick #include "clang/Lex/PreprocessorOptions.h"
32e5dd7070Spatrick #include "llvm/ADT/DenseMap.h"
33e5dd7070Spatrick #include "llvm/ADT/SetVector.h"
34e5dd7070Spatrick #include "llvm/ADT/SmallPtrSet.h"
35e5dd7070Spatrick #include "llvm/ADT/StringMap.h"
36e5dd7070Spatrick #include "llvm/IR/Module.h"
37e5dd7070Spatrick #include "llvm/IR/ValueHandle.h"
38e5dd7070Spatrick #include "llvm/Transforms/Utils/SanitizerStats.h"
39*12c85518Srobert #include <optional>
40e5dd7070Spatrick 
41e5dd7070Spatrick namespace llvm {
42e5dd7070Spatrick class Module;
43e5dd7070Spatrick class Constant;
44e5dd7070Spatrick class ConstantInt;
45e5dd7070Spatrick class Function;
46e5dd7070Spatrick class GlobalValue;
47e5dd7070Spatrick class DataLayout;
48e5dd7070Spatrick class FunctionType;
49e5dd7070Spatrick class LLVMContext;
50e5dd7070Spatrick class IndexedInstrProfReader;
51*12c85518Srobert 
52*12c85518Srobert namespace vfs {
53*12c85518Srobert class FileSystem;
54*12c85518Srobert }
55e5dd7070Spatrick }
56e5dd7070Spatrick 
57e5dd7070Spatrick namespace clang {
58e5dd7070Spatrick class ASTContext;
59e5dd7070Spatrick class AtomicType;
60e5dd7070Spatrick class FunctionDecl;
61e5dd7070Spatrick class IdentifierInfo;
62e5dd7070Spatrick class ObjCImplementationDecl;
63e5dd7070Spatrick class ObjCEncodeExpr;
64e5dd7070Spatrick class BlockExpr;
65e5dd7070Spatrick class CharUnits;
66e5dd7070Spatrick class Decl;
67e5dd7070Spatrick class Expr;
68e5dd7070Spatrick class Stmt;
69e5dd7070Spatrick class StringLiteral;
70e5dd7070Spatrick class NamedDecl;
71e5dd7070Spatrick class ValueDecl;
72e5dd7070Spatrick class VarDecl;
73e5dd7070Spatrick class LangOptions;
74e5dd7070Spatrick class CodeGenOptions;
75e5dd7070Spatrick class HeaderSearchOptions;
76e5dd7070Spatrick class DiagnosticsEngine;
77e5dd7070Spatrick class AnnotateAttr;
78e5dd7070Spatrick class CXXDestructorDecl;
79e5dd7070Spatrick class Module;
80e5dd7070Spatrick class CoverageSourceInfo;
81e5dd7070Spatrick class InitSegAttr;
82e5dd7070Spatrick 
83e5dd7070Spatrick namespace CodeGen {
84e5dd7070Spatrick 
85e5dd7070Spatrick class CodeGenFunction;
86e5dd7070Spatrick class CodeGenTBAA;
87e5dd7070Spatrick class CGCXXABI;
88e5dd7070Spatrick class CGDebugInfo;
89e5dd7070Spatrick class CGObjCRuntime;
90e5dd7070Spatrick class CGOpenCLRuntime;
91e5dd7070Spatrick class CGOpenMPRuntime;
92e5dd7070Spatrick class CGCUDARuntime;
93*12c85518Srobert class CGHLSLRuntime;
94e5dd7070Spatrick class CoverageMappingModuleGen;
95e5dd7070Spatrick class TargetCodeGenInfo;
96e5dd7070Spatrick 
97e5dd7070Spatrick enum ForDefinition_t : bool {
98e5dd7070Spatrick   NotForDefinition = false,
99e5dd7070Spatrick   ForDefinition = true
100e5dd7070Spatrick };
101e5dd7070Spatrick 
102a9ac8606Spatrick struct OrderGlobalInitsOrStermFinalizers {
103e5dd7070Spatrick   unsigned int priority;
104e5dd7070Spatrick   unsigned int lex_order;
OrderGlobalInitsOrStermFinalizersOrderGlobalInitsOrStermFinalizers105a9ac8606Spatrick   OrderGlobalInitsOrStermFinalizers(unsigned int p, unsigned int l)
106e5dd7070Spatrick       : priority(p), lex_order(l) {}
107e5dd7070Spatrick 
108a9ac8606Spatrick   bool operator==(const OrderGlobalInitsOrStermFinalizers &RHS) const {
109e5dd7070Spatrick     return priority == RHS.priority && lex_order == RHS.lex_order;
110e5dd7070Spatrick   }
111e5dd7070Spatrick 
112a9ac8606Spatrick   bool operator<(const OrderGlobalInitsOrStermFinalizers &RHS) const {
113e5dd7070Spatrick     return std::tie(priority, lex_order) <
114e5dd7070Spatrick            std::tie(RHS.priority, RHS.lex_order);
115e5dd7070Spatrick   }
116e5dd7070Spatrick };
117e5dd7070Spatrick 
118e5dd7070Spatrick struct ObjCEntrypoints {
ObjCEntrypointsObjCEntrypoints119e5dd7070Spatrick   ObjCEntrypoints() { memset(this, 0, sizeof(*this)); }
120e5dd7070Spatrick 
121e5dd7070Spatrick   /// void objc_alloc(id);
122e5dd7070Spatrick   llvm::FunctionCallee objc_alloc;
123e5dd7070Spatrick 
124e5dd7070Spatrick   /// void objc_allocWithZone(id);
125e5dd7070Spatrick   llvm::FunctionCallee objc_allocWithZone;
126e5dd7070Spatrick 
127e5dd7070Spatrick   /// void objc_alloc_init(id);
128e5dd7070Spatrick   llvm::FunctionCallee objc_alloc_init;
129e5dd7070Spatrick 
130e5dd7070Spatrick   /// void objc_autoreleasePoolPop(void*);
131e5dd7070Spatrick   llvm::FunctionCallee objc_autoreleasePoolPop;
132e5dd7070Spatrick 
133e5dd7070Spatrick   /// void objc_autoreleasePoolPop(void*);
134e5dd7070Spatrick   /// Note this method is used when we are using exception handling
135e5dd7070Spatrick   llvm::FunctionCallee objc_autoreleasePoolPopInvoke;
136e5dd7070Spatrick 
137e5dd7070Spatrick   /// void *objc_autoreleasePoolPush(void);
138e5dd7070Spatrick   llvm::Function *objc_autoreleasePoolPush;
139e5dd7070Spatrick 
140e5dd7070Spatrick   /// id objc_autorelease(id);
141e5dd7070Spatrick   llvm::Function *objc_autorelease;
142e5dd7070Spatrick 
143e5dd7070Spatrick   /// id objc_autorelease(id);
144e5dd7070Spatrick   /// Note this is the runtime method not the intrinsic.
145e5dd7070Spatrick   llvm::FunctionCallee objc_autoreleaseRuntimeFunction;
146e5dd7070Spatrick 
147e5dd7070Spatrick   /// id objc_autoreleaseReturnValue(id);
148e5dd7070Spatrick   llvm::Function *objc_autoreleaseReturnValue;
149e5dd7070Spatrick 
150e5dd7070Spatrick   /// void objc_copyWeak(id *dest, id *src);
151e5dd7070Spatrick   llvm::Function *objc_copyWeak;
152e5dd7070Spatrick 
153e5dd7070Spatrick   /// void objc_destroyWeak(id*);
154e5dd7070Spatrick   llvm::Function *objc_destroyWeak;
155e5dd7070Spatrick 
156e5dd7070Spatrick   /// id objc_initWeak(id*, id);
157e5dd7070Spatrick   llvm::Function *objc_initWeak;
158e5dd7070Spatrick 
159e5dd7070Spatrick   /// id objc_loadWeak(id*);
160e5dd7070Spatrick   llvm::Function *objc_loadWeak;
161e5dd7070Spatrick 
162e5dd7070Spatrick   /// id objc_loadWeakRetained(id*);
163e5dd7070Spatrick   llvm::Function *objc_loadWeakRetained;
164e5dd7070Spatrick 
165e5dd7070Spatrick   /// void objc_moveWeak(id *dest, id *src);
166e5dd7070Spatrick   llvm::Function *objc_moveWeak;
167e5dd7070Spatrick 
168e5dd7070Spatrick   /// id objc_retain(id);
169e5dd7070Spatrick   llvm::Function *objc_retain;
170e5dd7070Spatrick 
171e5dd7070Spatrick   /// id objc_retain(id);
172e5dd7070Spatrick   /// Note this is the runtime method not the intrinsic.
173e5dd7070Spatrick   llvm::FunctionCallee objc_retainRuntimeFunction;
174e5dd7070Spatrick 
175e5dd7070Spatrick   /// id objc_retainAutorelease(id);
176e5dd7070Spatrick   llvm::Function *objc_retainAutorelease;
177e5dd7070Spatrick 
178e5dd7070Spatrick   /// id objc_retainAutoreleaseReturnValue(id);
179e5dd7070Spatrick   llvm::Function *objc_retainAutoreleaseReturnValue;
180e5dd7070Spatrick 
181e5dd7070Spatrick   /// id objc_retainAutoreleasedReturnValue(id);
182e5dd7070Spatrick   llvm::Function *objc_retainAutoreleasedReturnValue;
183e5dd7070Spatrick 
184e5dd7070Spatrick   /// id objc_retainBlock(id);
185e5dd7070Spatrick   llvm::Function *objc_retainBlock;
186e5dd7070Spatrick 
187e5dd7070Spatrick   /// void objc_release(id);
188e5dd7070Spatrick   llvm::Function *objc_release;
189e5dd7070Spatrick 
190e5dd7070Spatrick   /// void objc_release(id);
191e5dd7070Spatrick   /// Note this is the runtime method not the intrinsic.
192e5dd7070Spatrick   llvm::FunctionCallee objc_releaseRuntimeFunction;
193e5dd7070Spatrick 
194e5dd7070Spatrick   /// void objc_storeStrong(id*, id);
195e5dd7070Spatrick   llvm::Function *objc_storeStrong;
196e5dd7070Spatrick 
197e5dd7070Spatrick   /// id objc_storeWeak(id*, id);
198e5dd7070Spatrick   llvm::Function *objc_storeWeak;
199e5dd7070Spatrick 
200e5dd7070Spatrick   /// id objc_unsafeClaimAutoreleasedReturnValue(id);
201e5dd7070Spatrick   llvm::Function *objc_unsafeClaimAutoreleasedReturnValue;
202e5dd7070Spatrick 
203e5dd7070Spatrick   /// A void(void) inline asm to use to mark that the return value of
204e5dd7070Spatrick   /// a call will be immediately retain.
205e5dd7070Spatrick   llvm::InlineAsm *retainAutoreleasedReturnValueMarker;
206e5dd7070Spatrick 
207e5dd7070Spatrick   /// void clang.arc.use(...);
208e5dd7070Spatrick   llvm::Function *clang_arc_use;
209a9ac8606Spatrick 
210a9ac8606Spatrick   /// void clang.arc.noop.use(...);
211a9ac8606Spatrick   llvm::Function *clang_arc_noop_use;
212e5dd7070Spatrick };
213e5dd7070Spatrick 
214e5dd7070Spatrick /// This class records statistics on instrumentation based profiling.
215e5dd7070Spatrick class InstrProfStats {
216e5dd7070Spatrick   uint32_t VisitedInMainFile;
217e5dd7070Spatrick   uint32_t MissingInMainFile;
218e5dd7070Spatrick   uint32_t Visited;
219e5dd7070Spatrick   uint32_t Missing;
220e5dd7070Spatrick   uint32_t Mismatched;
221e5dd7070Spatrick 
222e5dd7070Spatrick public:
InstrProfStats()223e5dd7070Spatrick   InstrProfStats()
224e5dd7070Spatrick       : VisitedInMainFile(0), MissingInMainFile(0), Visited(0), Missing(0),
225e5dd7070Spatrick         Mismatched(0) {}
226e5dd7070Spatrick   /// Record that we've visited a function and whether or not that function was
227e5dd7070Spatrick   /// in the main source file.
addVisited(bool MainFile)228e5dd7070Spatrick   void addVisited(bool MainFile) {
229e5dd7070Spatrick     if (MainFile)
230e5dd7070Spatrick       ++VisitedInMainFile;
231e5dd7070Spatrick     ++Visited;
232e5dd7070Spatrick   }
233e5dd7070Spatrick   /// Record that a function we've visited has no profile data.
addMissing(bool MainFile)234e5dd7070Spatrick   void addMissing(bool MainFile) {
235e5dd7070Spatrick     if (MainFile)
236e5dd7070Spatrick       ++MissingInMainFile;
237e5dd7070Spatrick     ++Missing;
238e5dd7070Spatrick   }
239e5dd7070Spatrick   /// Record that a function we've visited has mismatched profile data.
addMismatched(bool MainFile)240e5dd7070Spatrick   void addMismatched(bool MainFile) { ++Mismatched; }
241e5dd7070Spatrick   /// Whether or not the stats we've gathered indicate any potential problems.
hasDiagnostics()242e5dd7070Spatrick   bool hasDiagnostics() { return Missing || Mismatched; }
243e5dd7070Spatrick   /// Report potential problems we've found to \c Diags.
244e5dd7070Spatrick   void reportDiagnostics(DiagnosticsEngine &Diags, StringRef MainFile);
245e5dd7070Spatrick };
246e5dd7070Spatrick 
247e5dd7070Spatrick /// A pair of helper functions for a __block variable.
248e5dd7070Spatrick class BlockByrefHelpers : public llvm::FoldingSetNode {
249e5dd7070Spatrick   // MSVC requires this type to be complete in order to process this
250e5dd7070Spatrick   // header.
251e5dd7070Spatrick public:
252e5dd7070Spatrick   llvm::Constant *CopyHelper;
253e5dd7070Spatrick   llvm::Constant *DisposeHelper;
254e5dd7070Spatrick 
255e5dd7070Spatrick   /// The alignment of the field.  This is important because
256e5dd7070Spatrick   /// different offsets to the field within the byref struct need to
257e5dd7070Spatrick   /// have different helper functions.
258e5dd7070Spatrick   CharUnits Alignment;
259e5dd7070Spatrick 
BlockByrefHelpers(CharUnits alignment)260e5dd7070Spatrick   BlockByrefHelpers(CharUnits alignment)
261e5dd7070Spatrick       : CopyHelper(nullptr), DisposeHelper(nullptr), Alignment(alignment) {}
262e5dd7070Spatrick   BlockByrefHelpers(const BlockByrefHelpers &) = default;
263e5dd7070Spatrick   virtual ~BlockByrefHelpers();
264e5dd7070Spatrick 
Profile(llvm::FoldingSetNodeID & id)265e5dd7070Spatrick   void Profile(llvm::FoldingSetNodeID &id) const {
266e5dd7070Spatrick     id.AddInteger(Alignment.getQuantity());
267e5dd7070Spatrick     profileImpl(id);
268e5dd7070Spatrick   }
269e5dd7070Spatrick   virtual void profileImpl(llvm::FoldingSetNodeID &id) const = 0;
270e5dd7070Spatrick 
needsCopy()271e5dd7070Spatrick   virtual bool needsCopy() const { return true; }
272e5dd7070Spatrick   virtual void emitCopy(CodeGenFunction &CGF, Address dest, Address src) = 0;
273e5dd7070Spatrick 
needsDispose()274e5dd7070Spatrick   virtual bool needsDispose() const { return true; }
275e5dd7070Spatrick   virtual void emitDispose(CodeGenFunction &CGF, Address field) = 0;
276e5dd7070Spatrick };
277e5dd7070Spatrick 
278e5dd7070Spatrick /// This class organizes the cross-function state that is used while generating
279e5dd7070Spatrick /// LLVM code.
280e5dd7070Spatrick class CodeGenModule : public CodeGenTypeCache {
281e5dd7070Spatrick   CodeGenModule(const CodeGenModule &) = delete;
282e5dd7070Spatrick   void operator=(const CodeGenModule &) = delete;
283e5dd7070Spatrick 
284e5dd7070Spatrick public:
285e5dd7070Spatrick   struct Structor {
StructorStructor286*12c85518Srobert     Structor()
287*12c85518Srobert         : Priority(0), LexOrder(~0u), Initializer(nullptr),
288*12c85518Srobert           AssociatedData(nullptr) {}
StructorStructor289*12c85518Srobert     Structor(int Priority, unsigned LexOrder, llvm::Constant *Initializer,
290e5dd7070Spatrick              llvm::Constant *AssociatedData)
291*12c85518Srobert         : Priority(Priority), LexOrder(LexOrder), Initializer(Initializer),
292e5dd7070Spatrick           AssociatedData(AssociatedData) {}
293e5dd7070Spatrick     int Priority;
294*12c85518Srobert     unsigned LexOrder;
295e5dd7070Spatrick     llvm::Constant *Initializer;
296e5dd7070Spatrick     llvm::Constant *AssociatedData;
297e5dd7070Spatrick   };
298e5dd7070Spatrick 
299e5dd7070Spatrick   typedef std::vector<Structor> CtorList;
300e5dd7070Spatrick 
301e5dd7070Spatrick private:
302e5dd7070Spatrick   ASTContext &Context;
303e5dd7070Spatrick   const LangOptions &LangOpts;
304*12c85518Srobert   IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; // Only used for debug info.
305e5dd7070Spatrick   const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info.
306e5dd7070Spatrick   const PreprocessorOptions &PreprocessorOpts; // Only used for debug info.
307e5dd7070Spatrick   const CodeGenOptions &CodeGenOpts;
308ec727ea7Spatrick   unsigned NumAutoVarInit = 0;
309e5dd7070Spatrick   llvm::Module &TheModule;
310e5dd7070Spatrick   DiagnosticsEngine &Diags;
311e5dd7070Spatrick   const TargetInfo &Target;
312e5dd7070Spatrick   std::unique_ptr<CGCXXABI> ABI;
313e5dd7070Spatrick   llvm::LLVMContext &VMContext;
314*12c85518Srobert   std::string ModuleNameHash;
315*12c85518Srobert   bool CXX20ModuleInits = false;
316e5dd7070Spatrick   std::unique_ptr<CodeGenTBAA> TBAA;
317e5dd7070Spatrick 
318e5dd7070Spatrick   mutable std::unique_ptr<TargetCodeGenInfo> TheTargetCodeGenInfo;
319e5dd7070Spatrick 
320e5dd7070Spatrick   // This should not be moved earlier, since its initialization depends on some
321e5dd7070Spatrick   // of the previous reference members being already initialized and also checks
322e5dd7070Spatrick   // if TheTargetCodeGenInfo is NULL
323e5dd7070Spatrick   CodeGenTypes Types;
324e5dd7070Spatrick 
325e5dd7070Spatrick   /// Holds information about C++ vtables.
326e5dd7070Spatrick   CodeGenVTables VTables;
327e5dd7070Spatrick 
328e5dd7070Spatrick   std::unique_ptr<CGObjCRuntime> ObjCRuntime;
329e5dd7070Spatrick   std::unique_ptr<CGOpenCLRuntime> OpenCLRuntime;
330e5dd7070Spatrick   std::unique_ptr<CGOpenMPRuntime> OpenMPRuntime;
331e5dd7070Spatrick   std::unique_ptr<CGCUDARuntime> CUDARuntime;
332*12c85518Srobert   std::unique_ptr<CGHLSLRuntime> HLSLRuntime;
333e5dd7070Spatrick   std::unique_ptr<CGDebugInfo> DebugInfo;
334e5dd7070Spatrick   std::unique_ptr<ObjCEntrypoints> ObjCData;
335e5dd7070Spatrick   llvm::MDNode *NoObjCARCExceptionsMetadata = nullptr;
336e5dd7070Spatrick   std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader;
337e5dd7070Spatrick   InstrProfStats PGOStats;
338e5dd7070Spatrick   std::unique_ptr<llvm::SanitizerStatReport> SanStats;
339e5dd7070Spatrick 
340e5dd7070Spatrick   // A set of references that have only been seen via a weakref so far. This is
341e5dd7070Spatrick   // used to remove the weak of the reference if we ever see a direct reference
342e5dd7070Spatrick   // or a definition.
343e5dd7070Spatrick   llvm::SmallPtrSet<llvm::GlobalValue*, 10> WeakRefReferences;
344e5dd7070Spatrick 
345e5dd7070Spatrick   /// This contains all the decls which have definitions but/ which are deferred
346e5dd7070Spatrick   /// for emission and therefore should only be output if they are actually
347e5dd7070Spatrick   /// used. If a decl is in this, then it is known to have not been referenced
348e5dd7070Spatrick   /// yet.
349*12c85518Srobert   llvm::DenseMap<StringRef, GlobalDecl> DeferredDecls;
350e5dd7070Spatrick 
351e5dd7070Spatrick   /// This is a list of deferred decls which we have seen that *are* actually
352e5dd7070Spatrick   /// referenced. These get code generated when the module is done.
353e5dd7070Spatrick   std::vector<GlobalDecl> DeferredDeclsToEmit;
addDeferredDeclToEmit(GlobalDecl GD)354e5dd7070Spatrick   void addDeferredDeclToEmit(GlobalDecl GD) {
355e5dd7070Spatrick     DeferredDeclsToEmit.emplace_back(GD);
356*12c85518Srobert     addEmittedDeferredDecl(GD);
357*12c85518Srobert   }
358*12c85518Srobert 
359*12c85518Srobert   /// Decls that were DeferredDecls and have now been emitted.
360*12c85518Srobert   llvm::DenseMap<llvm::StringRef, GlobalDecl> EmittedDeferredDecls;
361*12c85518Srobert 
addEmittedDeferredDecl(GlobalDecl GD)362*12c85518Srobert   void addEmittedDeferredDecl(GlobalDecl GD) {
363*12c85518Srobert     if (!llvm::isa<FunctionDecl>(GD.getDecl()))
364*12c85518Srobert       return;
365*12c85518Srobert     llvm::GlobalVariable::LinkageTypes L = getFunctionLinkage(GD);
366*12c85518Srobert     if (llvm::GlobalValue::isLinkOnceLinkage(L) ||
367*12c85518Srobert         llvm::GlobalValue::isWeakLinkage(L)) {
368*12c85518Srobert       EmittedDeferredDecls[getMangledName(GD)] = GD;
369*12c85518Srobert     }
370e5dd7070Spatrick   }
371e5dd7070Spatrick 
372e5dd7070Spatrick   /// List of alias we have emitted. Used to make sure that what they point to
373e5dd7070Spatrick   /// is defined once we get to the end of the of the translation unit.
374e5dd7070Spatrick   std::vector<GlobalDecl> Aliases;
375e5dd7070Spatrick 
376*12c85518Srobert   /// List of multiversion functions to be emitted. This list is processed in
377*12c85518Srobert   /// conjunction with other deferred symbols and is used to ensure that
378*12c85518Srobert   /// multiversion function resolvers and ifuncs are defined and emitted.
379e5dd7070Spatrick   std::vector<GlobalDecl> MultiVersionFuncs;
380e5dd7070Spatrick 
381e5dd7070Spatrick   typedef llvm::StringMap<llvm::TrackingVH<llvm::Constant> > ReplacementsTy;
382e5dd7070Spatrick   ReplacementsTy Replacements;
383e5dd7070Spatrick 
384e5dd7070Spatrick   /// List of global values to be replaced with something else. Used when we
385e5dd7070Spatrick   /// want to replace a GlobalValue but can't identify it by its mangled name
386e5dd7070Spatrick   /// anymore (because the name is already taken).
387e5dd7070Spatrick   llvm::SmallVector<std::pair<llvm::GlobalValue *, llvm::Constant *>, 8>
388e5dd7070Spatrick     GlobalValReplacements;
389e5dd7070Spatrick 
390e5dd7070Spatrick   /// Variables for which we've emitted globals containing their constant
391e5dd7070Spatrick   /// values along with the corresponding globals, for opportunistic reuse.
392e5dd7070Spatrick   llvm::DenseMap<const VarDecl*, llvm::GlobalVariable*> InitializerConstants;
393e5dd7070Spatrick 
394e5dd7070Spatrick   /// Set of global decls for which we already diagnosed mangled name conflict.
395e5dd7070Spatrick   /// Required to not issue a warning (on a mangling conflict) multiple times
396e5dd7070Spatrick   /// for the same decl.
397e5dd7070Spatrick   llvm::DenseSet<GlobalDecl> DiagnosedConflictingDefinitions;
398e5dd7070Spatrick 
399e5dd7070Spatrick   /// A queue of (optional) vtables to consider emitting.
400e5dd7070Spatrick   std::vector<const CXXRecordDecl*> DeferredVTables;
401e5dd7070Spatrick 
402e5dd7070Spatrick   /// A queue of (optional) vtables that may be emitted opportunistically.
403e5dd7070Spatrick   std::vector<const CXXRecordDecl *> OpportunisticVTables;
404e5dd7070Spatrick 
405e5dd7070Spatrick   /// List of global values which are required to be present in the object file;
406e5dd7070Spatrick   /// bitcast to i8*. This is used for forcing visibility of symbols which may
407e5dd7070Spatrick   /// otherwise be optimized out.
408e5dd7070Spatrick   std::vector<llvm::WeakTrackingVH> LLVMUsed;
409e5dd7070Spatrick   std::vector<llvm::WeakTrackingVH> LLVMCompilerUsed;
410e5dd7070Spatrick 
411e5dd7070Spatrick   /// Store the list of global constructors and their respective priorities to
412e5dd7070Spatrick   /// be emitted when the translation unit is complete.
413e5dd7070Spatrick   CtorList GlobalCtors;
414e5dd7070Spatrick 
415e5dd7070Spatrick   /// Store the list of global destructors and their respective priorities to be
416e5dd7070Spatrick   /// emitted when the translation unit is complete.
417e5dd7070Spatrick   CtorList GlobalDtors;
418e5dd7070Spatrick 
419e5dd7070Spatrick   /// An ordered map of canonical GlobalDecls to their mangled names.
420e5dd7070Spatrick   llvm::MapVector<GlobalDecl, StringRef> MangledDeclNames;
421e5dd7070Spatrick   llvm::StringMap<GlobalDecl, llvm::BumpPtrAllocator> Manglings;
422e5dd7070Spatrick 
423e5dd7070Spatrick   /// Global annotations.
424e5dd7070Spatrick   std::vector<llvm::Constant*> Annotations;
425e5dd7070Spatrick 
426e5dd7070Spatrick   /// Map used to get unique annotation strings.
427e5dd7070Spatrick   llvm::StringMap<llvm::Constant*> AnnotationStrings;
428e5dd7070Spatrick 
429a9ac8606Spatrick   /// Used for uniquing of annotation arguments.
430a9ac8606Spatrick   llvm::DenseMap<unsigned, llvm::Constant *> AnnotationArgs;
431a9ac8606Spatrick 
432e5dd7070Spatrick   llvm::StringMap<llvm::GlobalVariable *> CFConstantStringMap;
433e5dd7070Spatrick 
434e5dd7070Spatrick   llvm::DenseMap<llvm::Constant *, llvm::GlobalVariable *> ConstantStringMap;
435*12c85518Srobert   llvm::DenseMap<const UnnamedGlobalConstantDecl *, llvm::GlobalVariable *>
436*12c85518Srobert       UnnamedGlobalConstantDeclMap;
437e5dd7070Spatrick   llvm::DenseMap<const Decl*, llvm::Constant *> StaticLocalDeclMap;
438e5dd7070Spatrick   llvm::DenseMap<const Decl*, llvm::GlobalVariable*> StaticLocalDeclGuardMap;
439e5dd7070Spatrick   llvm::DenseMap<const Expr*, llvm::Constant *> MaterializedGlobalTemporaryMap;
440e5dd7070Spatrick 
441e5dd7070Spatrick   llvm::DenseMap<QualType, llvm::Constant *> AtomicSetterHelperFnMap;
442e5dd7070Spatrick   llvm::DenseMap<QualType, llvm::Constant *> AtomicGetterHelperFnMap;
443e5dd7070Spatrick 
444e5dd7070Spatrick   /// Map used to get unique type descriptor constants for sanitizers.
445e5dd7070Spatrick   llvm::DenseMap<QualType, llvm::Constant *> TypeDescriptorMap;
446e5dd7070Spatrick 
447e5dd7070Spatrick   /// Map used to track internal linkage functions declared within
448e5dd7070Spatrick   /// extern "C" regions.
449e5dd7070Spatrick   typedef llvm::MapVector<IdentifierInfo *,
450e5dd7070Spatrick                           llvm::GlobalValue *> StaticExternCMap;
451e5dd7070Spatrick   StaticExternCMap StaticExternCValues;
452e5dd7070Spatrick 
453e5dd7070Spatrick   /// thread_local variables defined or used in this TU.
454e5dd7070Spatrick   std::vector<const VarDecl *> CXXThreadLocals;
455e5dd7070Spatrick 
456e5dd7070Spatrick   /// thread_local variables with initializers that need to run
457e5dd7070Spatrick   /// before any thread_local variable in this TU is odr-used.
458e5dd7070Spatrick   std::vector<llvm::Function *> CXXThreadLocalInits;
459e5dd7070Spatrick   std::vector<const VarDecl *> CXXThreadLocalInitVars;
460e5dd7070Spatrick 
461e5dd7070Spatrick   /// Global variables with initializers that need to run before main.
462e5dd7070Spatrick   std::vector<llvm::Function *> CXXGlobalInits;
463e5dd7070Spatrick 
464e5dd7070Spatrick   /// When a C++ decl with an initializer is deferred, null is
465e5dd7070Spatrick   /// appended to CXXGlobalInits, and the index of that null is placed
466e5dd7070Spatrick   /// here so that the initializer will be performed in the correct
467e5dd7070Spatrick   /// order. Once the decl is emitted, the index is replaced with ~0U to ensure
468e5dd7070Spatrick   /// that we don't re-emit the initializer.
469e5dd7070Spatrick   llvm::DenseMap<const Decl*, unsigned> DelayedCXXInitPosition;
470e5dd7070Spatrick 
471a9ac8606Spatrick   typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *>
472a9ac8606Spatrick       GlobalInitData;
473e5dd7070Spatrick 
474e5dd7070Spatrick   struct GlobalInitPriorityCmp {
operatorGlobalInitPriorityCmp475e5dd7070Spatrick     bool operator()(const GlobalInitData &LHS,
476e5dd7070Spatrick                     const GlobalInitData &RHS) const {
477e5dd7070Spatrick       return LHS.first.priority < RHS.first.priority;
478e5dd7070Spatrick     }
479e5dd7070Spatrick   };
480e5dd7070Spatrick 
481e5dd7070Spatrick   /// Global variables with initializers whose order of initialization is set by
482e5dd7070Spatrick   /// init_priority attribute.
483e5dd7070Spatrick   SmallVector<GlobalInitData, 8> PrioritizedCXXGlobalInits;
484e5dd7070Spatrick 
485e5dd7070Spatrick   /// Global destructor functions and arguments that need to run on termination.
486ec727ea7Spatrick   /// When UseSinitAndSterm is set, it instead contains sterm finalizer
487ec727ea7Spatrick   /// functions, which also run on unloading a shared library.
488a9ac8606Spatrick   typedef std::tuple<llvm::FunctionType *, llvm::WeakTrackingVH,
489a9ac8606Spatrick                      llvm::Constant *>
490a9ac8606Spatrick       CXXGlobalDtorsOrStermFinalizer_t;
491a9ac8606Spatrick   SmallVector<CXXGlobalDtorsOrStermFinalizer_t, 8>
492ec727ea7Spatrick       CXXGlobalDtorsOrStermFinalizers;
493e5dd7070Spatrick 
494a9ac8606Spatrick   typedef std::pair<OrderGlobalInitsOrStermFinalizers, llvm::Function *>
495a9ac8606Spatrick       StermFinalizerData;
496a9ac8606Spatrick 
497a9ac8606Spatrick   struct StermFinalizerPriorityCmp {
operatorStermFinalizerPriorityCmp498a9ac8606Spatrick     bool operator()(const StermFinalizerData &LHS,
499a9ac8606Spatrick                     const StermFinalizerData &RHS) const {
500a9ac8606Spatrick       return LHS.first.priority < RHS.first.priority;
501a9ac8606Spatrick     }
502a9ac8606Spatrick   };
503a9ac8606Spatrick 
504a9ac8606Spatrick   /// Global variables with sterm finalizers whose order of initialization is
505a9ac8606Spatrick   /// set by init_priority attribute.
506a9ac8606Spatrick   SmallVector<StermFinalizerData, 8> PrioritizedCXXStermFinalizers;
507a9ac8606Spatrick 
508e5dd7070Spatrick   /// The complete set of modules that has been imported.
509e5dd7070Spatrick   llvm::SetVector<clang::Module *> ImportedModules;
510e5dd7070Spatrick 
511e5dd7070Spatrick   /// The set of modules for which the module initializers
512e5dd7070Spatrick   /// have been emitted.
513e5dd7070Spatrick   llvm::SmallPtrSet<clang::Module *, 16> EmittedModuleInitializers;
514e5dd7070Spatrick 
515e5dd7070Spatrick   /// A vector of metadata strings for linker options.
516e5dd7070Spatrick   SmallVector<llvm::MDNode *, 16> LinkerOptionsMetadata;
517e5dd7070Spatrick 
518e5dd7070Spatrick   /// A vector of metadata strings for dependent libraries for ELF.
519e5dd7070Spatrick   SmallVector<llvm::MDNode *, 16> ELFDependentLibraries;
520e5dd7070Spatrick 
521e5dd7070Spatrick   /// @name Cache for Objective-C runtime types
522e5dd7070Spatrick   /// @{
523e5dd7070Spatrick 
524e5dd7070Spatrick   /// Cached reference to the class for constant strings. This value has type
525e5dd7070Spatrick   /// int * but is actually an Obj-C class pointer.
526e5dd7070Spatrick   llvm::WeakTrackingVH CFConstantStringClassRef;
527e5dd7070Spatrick 
528e5dd7070Spatrick   /// The type used to describe the state of a fast enumeration in
529e5dd7070Spatrick   /// Objective-C's for..in loop.
530e5dd7070Spatrick   QualType ObjCFastEnumerationStateType;
531e5dd7070Spatrick 
532e5dd7070Spatrick   /// @}
533e5dd7070Spatrick 
534e5dd7070Spatrick   /// Lazily create the Objective-C runtime
535e5dd7070Spatrick   void createObjCRuntime();
536e5dd7070Spatrick 
537e5dd7070Spatrick   void createOpenCLRuntime();
538e5dd7070Spatrick   void createOpenMPRuntime();
539e5dd7070Spatrick   void createCUDARuntime();
540*12c85518Srobert   void createHLSLRuntime();
541e5dd7070Spatrick 
542e5dd7070Spatrick   bool isTriviallyRecursive(const FunctionDecl *F);
543e5dd7070Spatrick   bool shouldEmitFunction(GlobalDecl GD);
544e5dd7070Spatrick   bool shouldOpportunisticallyEmitVTables();
545e5dd7070Spatrick   /// Map used to be sure we don't emit the same CompoundLiteral twice.
546e5dd7070Spatrick   llvm::DenseMap<const CompoundLiteralExpr *, llvm::GlobalVariable *>
547e5dd7070Spatrick       EmittedCompoundLiterals;
548e5dd7070Spatrick 
549e5dd7070Spatrick   /// Map of the global blocks we've emitted, so that we don't have to re-emit
550e5dd7070Spatrick   /// them if the constexpr evaluator gets aggressive.
551e5dd7070Spatrick   llvm::DenseMap<const BlockExpr *, llvm::Constant *> EmittedGlobalBlocks;
552e5dd7070Spatrick 
553e5dd7070Spatrick   /// @name Cache for Blocks Runtime Globals
554e5dd7070Spatrick   /// @{
555e5dd7070Spatrick 
556e5dd7070Spatrick   llvm::Constant *NSConcreteGlobalBlock = nullptr;
557e5dd7070Spatrick   llvm::Constant *NSConcreteStackBlock = nullptr;
558e5dd7070Spatrick 
559e5dd7070Spatrick   llvm::FunctionCallee BlockObjectAssign = nullptr;
560e5dd7070Spatrick   llvm::FunctionCallee BlockObjectDispose = nullptr;
561e5dd7070Spatrick 
562e5dd7070Spatrick   llvm::Type *BlockDescriptorType = nullptr;
563e5dd7070Spatrick   llvm::Type *GenericBlockLiteralType = nullptr;
564e5dd7070Spatrick 
565e5dd7070Spatrick   struct {
566e5dd7070Spatrick     int GlobalUniqueCount;
567e5dd7070Spatrick   } Block;
568e5dd7070Spatrick 
569e5dd7070Spatrick   GlobalDecl initializedGlobalDecl;
570e5dd7070Spatrick 
571e5dd7070Spatrick   /// @}
572e5dd7070Spatrick 
573e5dd7070Spatrick   /// void @llvm.lifetime.start(i64 %size, i8* nocapture <ptr>)
574e5dd7070Spatrick   llvm::Function *LifetimeStartFn = nullptr;
575e5dd7070Spatrick 
576e5dd7070Spatrick   /// void @llvm.lifetime.end(i64 %size, i8* nocapture <ptr>)
577e5dd7070Spatrick   llvm::Function *LifetimeEndFn = nullptr;
578e5dd7070Spatrick 
579e5dd7070Spatrick   std::unique_ptr<SanitizerMetadata> SanitizerMD;
580e5dd7070Spatrick 
581e5dd7070Spatrick   llvm::MapVector<const Decl *, bool> DeferredEmptyCoverageMappingDecls;
582e5dd7070Spatrick 
583e5dd7070Spatrick   std::unique_ptr<CoverageMappingModuleGen> CoverageMapping;
584e5dd7070Spatrick 
585e5dd7070Spatrick   /// Mapping from canonical types to their metadata identifiers. We need to
586e5dd7070Spatrick   /// maintain this mapping because identifiers may be formed from distinct
587e5dd7070Spatrick   /// MDNodes.
588e5dd7070Spatrick   typedef llvm::DenseMap<QualType, llvm::Metadata *> MetadataTypeMap;
589e5dd7070Spatrick   MetadataTypeMap MetadataIdMap;
590e5dd7070Spatrick   MetadataTypeMap VirtualMetadataIdMap;
591e5dd7070Spatrick   MetadataTypeMap GeneralizedMetadataIdMap;
592e5dd7070Spatrick 
593*12c85518Srobert   llvm::DenseMap<const llvm::Constant *, llvm::GlobalVariable *> RTTIProxyMap;
594*12c85518Srobert 
595*12c85518Srobert   // Helps squashing blocks of TopLevelStmtDecl into a single llvm::Function
596*12c85518Srobert   // when used with -fincremental-extensions.
597*12c85518Srobert   std::pair<std::unique_ptr<CodeGenFunction>, const TopLevelStmtDecl *>
598*12c85518Srobert       GlobalTopLevelStmtBlockInFlight;
599*12c85518Srobert 
600e5dd7070Spatrick public:
601*12c85518Srobert   CodeGenModule(ASTContext &C, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
602*12c85518Srobert                 const HeaderSearchOptions &headersearchopts,
603e5dd7070Spatrick                 const PreprocessorOptions &ppopts,
604e5dd7070Spatrick                 const CodeGenOptions &CodeGenOpts, llvm::Module &M,
605e5dd7070Spatrick                 DiagnosticsEngine &Diags,
606e5dd7070Spatrick                 CoverageSourceInfo *CoverageInfo = nullptr);
607e5dd7070Spatrick 
608e5dd7070Spatrick   ~CodeGenModule();
609e5dd7070Spatrick 
610e5dd7070Spatrick   void clear();
611e5dd7070Spatrick 
612e5dd7070Spatrick   /// Finalize LLVM code generation.
613e5dd7070Spatrick   void Release();
614e5dd7070Spatrick 
615e5dd7070Spatrick   /// Return true if we should emit location information for expressions.
616e5dd7070Spatrick   bool getExpressionLocationsEnabled() const;
617e5dd7070Spatrick 
618e5dd7070Spatrick   /// Return a reference to the configured Objective-C runtime.
getObjCRuntime()619e5dd7070Spatrick   CGObjCRuntime &getObjCRuntime() {
620e5dd7070Spatrick     if (!ObjCRuntime) createObjCRuntime();
621e5dd7070Spatrick     return *ObjCRuntime;
622e5dd7070Spatrick   }
623e5dd7070Spatrick 
624e5dd7070Spatrick   /// Return true iff an Objective-C runtime has been configured.
hasObjCRuntime()625e5dd7070Spatrick   bool hasObjCRuntime() { return !!ObjCRuntime; }
626e5dd7070Spatrick 
getModuleNameHash()627a9ac8606Spatrick   const std::string &getModuleNameHash() const { return ModuleNameHash; }
628a9ac8606Spatrick 
629e5dd7070Spatrick   /// Return a reference to the configured OpenCL runtime.
getOpenCLRuntime()630e5dd7070Spatrick   CGOpenCLRuntime &getOpenCLRuntime() {
631e5dd7070Spatrick     assert(OpenCLRuntime != nullptr);
632e5dd7070Spatrick     return *OpenCLRuntime;
633e5dd7070Spatrick   }
634e5dd7070Spatrick 
635e5dd7070Spatrick   /// Return a reference to the configured OpenMP runtime.
getOpenMPRuntime()636e5dd7070Spatrick   CGOpenMPRuntime &getOpenMPRuntime() {
637e5dd7070Spatrick     assert(OpenMPRuntime != nullptr);
638e5dd7070Spatrick     return *OpenMPRuntime;
639e5dd7070Spatrick   }
640e5dd7070Spatrick 
641e5dd7070Spatrick   /// Return a reference to the configured CUDA runtime.
getCUDARuntime()642e5dd7070Spatrick   CGCUDARuntime &getCUDARuntime() {
643e5dd7070Spatrick     assert(CUDARuntime != nullptr);
644e5dd7070Spatrick     return *CUDARuntime;
645e5dd7070Spatrick   }
646e5dd7070Spatrick 
647*12c85518Srobert   /// Return a reference to the configured HLSL runtime.
getHLSLRuntime()648*12c85518Srobert   CGHLSLRuntime &getHLSLRuntime() {
649*12c85518Srobert     assert(HLSLRuntime != nullptr);
650*12c85518Srobert     return *HLSLRuntime;
651*12c85518Srobert   }
652*12c85518Srobert 
getObjCEntrypoints()653e5dd7070Spatrick   ObjCEntrypoints &getObjCEntrypoints() const {
654e5dd7070Spatrick     assert(ObjCData != nullptr);
655e5dd7070Spatrick     return *ObjCData;
656e5dd7070Spatrick   }
657e5dd7070Spatrick 
658a9ac8606Spatrick   // Version checking functions, used to implement ObjC's @available:
659e5dd7070Spatrick   // i32 @__isOSVersionAtLeast(i32, i32, i32)
660e5dd7070Spatrick   llvm::FunctionCallee IsOSVersionAtLeastFn = nullptr;
661a9ac8606Spatrick   // i32 @__isPlatformVersionAtLeast(i32, i32, i32, i32)
662a9ac8606Spatrick   llvm::FunctionCallee IsPlatformVersionAtLeastFn = nullptr;
663e5dd7070Spatrick 
getPGOStats()664e5dd7070Spatrick   InstrProfStats &getPGOStats() { return PGOStats; }
getPGOReader()665e5dd7070Spatrick   llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); }
666e5dd7070Spatrick 
getCoverageMapping()667e5dd7070Spatrick   CoverageMappingModuleGen *getCoverageMapping() const {
668e5dd7070Spatrick     return CoverageMapping.get();
669e5dd7070Spatrick   }
670e5dd7070Spatrick 
getStaticLocalDeclAddress(const VarDecl * D)671e5dd7070Spatrick   llvm::Constant *getStaticLocalDeclAddress(const VarDecl *D) {
672e5dd7070Spatrick     return StaticLocalDeclMap[D];
673e5dd7070Spatrick   }
setStaticLocalDeclAddress(const VarDecl * D,llvm::Constant * C)674e5dd7070Spatrick   void setStaticLocalDeclAddress(const VarDecl *D,
675e5dd7070Spatrick                                  llvm::Constant *C) {
676e5dd7070Spatrick     StaticLocalDeclMap[D] = C;
677e5dd7070Spatrick   }
678e5dd7070Spatrick 
679e5dd7070Spatrick   llvm::Constant *
680e5dd7070Spatrick   getOrCreateStaticVarDecl(const VarDecl &D,
681e5dd7070Spatrick                            llvm::GlobalValue::LinkageTypes Linkage);
682e5dd7070Spatrick 
getStaticLocalDeclGuardAddress(const VarDecl * D)683e5dd7070Spatrick   llvm::GlobalVariable *getStaticLocalDeclGuardAddress(const VarDecl *D) {
684e5dd7070Spatrick     return StaticLocalDeclGuardMap[D];
685e5dd7070Spatrick   }
setStaticLocalDeclGuardAddress(const VarDecl * D,llvm::GlobalVariable * C)686e5dd7070Spatrick   void setStaticLocalDeclGuardAddress(const VarDecl *D,
687e5dd7070Spatrick                                       llvm::GlobalVariable *C) {
688e5dd7070Spatrick     StaticLocalDeclGuardMap[D] = C;
689e5dd7070Spatrick   }
690e5dd7070Spatrick 
691e5dd7070Spatrick   Address createUnnamedGlobalFrom(const VarDecl &D, llvm::Constant *Constant,
692e5dd7070Spatrick                                   CharUnits Align);
693e5dd7070Spatrick 
694e5dd7070Spatrick   bool lookupRepresentativeDecl(StringRef MangledName,
695e5dd7070Spatrick                                 GlobalDecl &Result) const;
696e5dd7070Spatrick 
getAtomicSetterHelperFnMap(QualType Ty)697e5dd7070Spatrick   llvm::Constant *getAtomicSetterHelperFnMap(QualType Ty) {
698e5dd7070Spatrick     return AtomicSetterHelperFnMap[Ty];
699e5dd7070Spatrick   }
setAtomicSetterHelperFnMap(QualType Ty,llvm::Constant * Fn)700e5dd7070Spatrick   void setAtomicSetterHelperFnMap(QualType Ty,
701e5dd7070Spatrick                             llvm::Constant *Fn) {
702e5dd7070Spatrick     AtomicSetterHelperFnMap[Ty] = Fn;
703e5dd7070Spatrick   }
704e5dd7070Spatrick 
getAtomicGetterHelperFnMap(QualType Ty)705e5dd7070Spatrick   llvm::Constant *getAtomicGetterHelperFnMap(QualType Ty) {
706e5dd7070Spatrick     return AtomicGetterHelperFnMap[Ty];
707e5dd7070Spatrick   }
setAtomicGetterHelperFnMap(QualType Ty,llvm::Constant * Fn)708e5dd7070Spatrick   void setAtomicGetterHelperFnMap(QualType Ty,
709e5dd7070Spatrick                             llvm::Constant *Fn) {
710e5dd7070Spatrick     AtomicGetterHelperFnMap[Ty] = Fn;
711e5dd7070Spatrick   }
712e5dd7070Spatrick 
getTypeDescriptorFromMap(QualType Ty)713e5dd7070Spatrick   llvm::Constant *getTypeDescriptorFromMap(QualType Ty) {
714e5dd7070Spatrick     return TypeDescriptorMap[Ty];
715e5dd7070Spatrick   }
setTypeDescriptorInMap(QualType Ty,llvm::Constant * C)716e5dd7070Spatrick   void setTypeDescriptorInMap(QualType Ty, llvm::Constant *C) {
717e5dd7070Spatrick     TypeDescriptorMap[Ty] = C;
718e5dd7070Spatrick   }
719e5dd7070Spatrick 
getModuleDebugInfo()720e5dd7070Spatrick   CGDebugInfo *getModuleDebugInfo() { return DebugInfo.get(); }
721e5dd7070Spatrick 
getNoObjCARCExceptionsMetadata()722e5dd7070Spatrick   llvm::MDNode *getNoObjCARCExceptionsMetadata() {
723e5dd7070Spatrick     if (!NoObjCARCExceptionsMetadata)
724*12c85518Srobert       NoObjCARCExceptionsMetadata =
725*12c85518Srobert           llvm::MDNode::get(getLLVMContext(), std::nullopt);
726e5dd7070Spatrick     return NoObjCARCExceptionsMetadata;
727e5dd7070Spatrick   }
728e5dd7070Spatrick 
getContext()729e5dd7070Spatrick   ASTContext &getContext() const { return Context; }
getLangOpts()730e5dd7070Spatrick   const LangOptions &getLangOpts() const { return LangOpts; }
getFileSystem()731*12c85518Srobert   const IntrusiveRefCntPtr<llvm::vfs::FileSystem> &getFileSystem() const {
732*12c85518Srobert     return FS;
733*12c85518Srobert   }
getHeaderSearchOpts()734e5dd7070Spatrick   const HeaderSearchOptions &getHeaderSearchOpts()
735e5dd7070Spatrick     const { return HeaderSearchOpts; }
getPreprocessorOpts()736e5dd7070Spatrick   const PreprocessorOptions &getPreprocessorOpts()
737e5dd7070Spatrick     const { return PreprocessorOpts; }
getCodeGenOpts()738e5dd7070Spatrick   const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; }
getModule()739e5dd7070Spatrick   llvm::Module &getModule() const { return TheModule; }
getDiags()740e5dd7070Spatrick   DiagnosticsEngine &getDiags() const { return Diags; }
getDataLayout()741e5dd7070Spatrick   const llvm::DataLayout &getDataLayout() const {
742e5dd7070Spatrick     return TheModule.getDataLayout();
743e5dd7070Spatrick   }
getTarget()744e5dd7070Spatrick   const TargetInfo &getTarget() const { return Target; }
getTriple()745e5dd7070Spatrick   const llvm::Triple &getTriple() const { return Target.getTriple(); }
746e5dd7070Spatrick   bool supportsCOMDAT() const;
747e5dd7070Spatrick   void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO);
748e5dd7070Spatrick 
getCXXABI()749e5dd7070Spatrick   CGCXXABI &getCXXABI() const { return *ABI; }
getLLVMContext()750e5dd7070Spatrick   llvm::LLVMContext &getLLVMContext() { return VMContext; }
751e5dd7070Spatrick 
shouldUseTBAA()752e5dd7070Spatrick   bool shouldUseTBAA() const { return TBAA != nullptr; }
753e5dd7070Spatrick 
754e5dd7070Spatrick   const TargetCodeGenInfo &getTargetCodeGenInfo();
755e5dd7070Spatrick 
getTypes()756e5dd7070Spatrick   CodeGenTypes &getTypes() { return Types; }
757e5dd7070Spatrick 
getVTables()758e5dd7070Spatrick   CodeGenVTables &getVTables() { return VTables; }
759e5dd7070Spatrick 
getItaniumVTableContext()760e5dd7070Spatrick   ItaniumVTableContext &getItaniumVTableContext() {
761e5dd7070Spatrick     return VTables.getItaniumVTableContext();
762e5dd7070Spatrick   }
763e5dd7070Spatrick 
getItaniumVTableContext()764*12c85518Srobert   const ItaniumVTableContext &getItaniumVTableContext() const {
765*12c85518Srobert     return VTables.getItaniumVTableContext();
766*12c85518Srobert   }
767*12c85518Srobert 
getMicrosoftVTableContext()768e5dd7070Spatrick   MicrosoftVTableContext &getMicrosoftVTableContext() {
769e5dd7070Spatrick     return VTables.getMicrosoftVTableContext();
770e5dd7070Spatrick   }
771e5dd7070Spatrick 
getGlobalCtors()772e5dd7070Spatrick   CtorList &getGlobalCtors() { return GlobalCtors; }
getGlobalDtors()773e5dd7070Spatrick   CtorList &getGlobalDtors() { return GlobalDtors; }
774e5dd7070Spatrick 
775e5dd7070Spatrick   /// getTBAATypeInfo - Get metadata used to describe accesses to objects of
776e5dd7070Spatrick   /// the given type.
777e5dd7070Spatrick   llvm::MDNode *getTBAATypeInfo(QualType QTy);
778e5dd7070Spatrick 
779e5dd7070Spatrick   /// getTBAAAccessInfo - Get TBAA information that describes an access to
780e5dd7070Spatrick   /// an object of the given type.
781e5dd7070Spatrick   TBAAAccessInfo getTBAAAccessInfo(QualType AccessType);
782e5dd7070Spatrick 
783e5dd7070Spatrick   /// getTBAAVTablePtrAccessInfo - Get the TBAA information that describes an
784e5dd7070Spatrick   /// access to a virtual table pointer.
785e5dd7070Spatrick   TBAAAccessInfo getTBAAVTablePtrAccessInfo(llvm::Type *VTablePtrType);
786e5dd7070Spatrick 
787e5dd7070Spatrick   llvm::MDNode *getTBAAStructInfo(QualType QTy);
788e5dd7070Spatrick 
789e5dd7070Spatrick   /// getTBAABaseTypeInfo - Get metadata that describes the given base access
790e5dd7070Spatrick   /// type. Return null if the type is not suitable for use in TBAA access tags.
791e5dd7070Spatrick   llvm::MDNode *getTBAABaseTypeInfo(QualType QTy);
792e5dd7070Spatrick 
793e5dd7070Spatrick   /// getTBAAAccessTagInfo - Get TBAA tag for a given memory access.
794e5dd7070Spatrick   llvm::MDNode *getTBAAAccessTagInfo(TBAAAccessInfo Info);
795e5dd7070Spatrick 
796e5dd7070Spatrick   /// mergeTBAAInfoForCast - Get merged TBAA information for the purposes of
797e5dd7070Spatrick   /// type casts.
798e5dd7070Spatrick   TBAAAccessInfo mergeTBAAInfoForCast(TBAAAccessInfo SourceInfo,
799e5dd7070Spatrick                                       TBAAAccessInfo TargetInfo);
800e5dd7070Spatrick 
801e5dd7070Spatrick   /// mergeTBAAInfoForConditionalOperator - Get merged TBAA information for the
802e5dd7070Spatrick   /// purposes of conditional operator.
803e5dd7070Spatrick   TBAAAccessInfo mergeTBAAInfoForConditionalOperator(TBAAAccessInfo InfoA,
804e5dd7070Spatrick                                                      TBAAAccessInfo InfoB);
805e5dd7070Spatrick 
806e5dd7070Spatrick   /// mergeTBAAInfoForMemoryTransfer - Get merged TBAA information for the
807e5dd7070Spatrick   /// purposes of memory transfer calls.
808e5dd7070Spatrick   TBAAAccessInfo mergeTBAAInfoForMemoryTransfer(TBAAAccessInfo DestInfo,
809e5dd7070Spatrick                                                 TBAAAccessInfo SrcInfo);
810e5dd7070Spatrick 
811e5dd7070Spatrick   /// getTBAAInfoForSubobject - Get TBAA information for an access with a given
812e5dd7070Spatrick   /// base lvalue.
getTBAAInfoForSubobject(LValue Base,QualType AccessType)813e5dd7070Spatrick   TBAAAccessInfo getTBAAInfoForSubobject(LValue Base, QualType AccessType) {
814e5dd7070Spatrick     if (Base.getTBAAInfo().isMayAlias())
815e5dd7070Spatrick       return TBAAAccessInfo::getMayAliasInfo();
816e5dd7070Spatrick     return getTBAAAccessInfo(AccessType);
817e5dd7070Spatrick   }
818e5dd7070Spatrick 
819e5dd7070Spatrick   bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor);
820e5dd7070Spatrick 
821e5dd7070Spatrick   bool isPaddedAtomicType(QualType type);
822e5dd7070Spatrick   bool isPaddedAtomicType(const AtomicType *type);
823e5dd7070Spatrick 
824e5dd7070Spatrick   /// DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag.
825e5dd7070Spatrick   void DecorateInstructionWithTBAA(llvm::Instruction *Inst,
826e5dd7070Spatrick                                    TBAAAccessInfo TBAAInfo);
827e5dd7070Spatrick 
828e5dd7070Spatrick   /// Adds !invariant.barrier !tag to instruction
829e5dd7070Spatrick   void DecorateInstructionWithInvariantGroup(llvm::Instruction *I,
830e5dd7070Spatrick                                              const CXXRecordDecl *RD);
831e5dd7070Spatrick 
832e5dd7070Spatrick   /// Emit the given number of characters as a value of type size_t.
833e5dd7070Spatrick   llvm::ConstantInt *getSize(CharUnits numChars);
834e5dd7070Spatrick 
835e5dd7070Spatrick   /// Set the visibility for the given LLVM GlobalValue.
836e5dd7070Spatrick   void setGlobalVisibility(llvm::GlobalValue *GV, const NamedDecl *D) const;
837e5dd7070Spatrick 
838e5dd7070Spatrick   void setDSOLocal(llvm::GlobalValue *GV) const;
839e5dd7070Spatrick 
shouldMapVisibilityToDLLExport(const NamedDecl * D)840*12c85518Srobert   bool shouldMapVisibilityToDLLExport(const NamedDecl *D) const {
841*12c85518Srobert     return getLangOpts().hasDefaultVisibilityExportMapping() && D &&
842*12c85518Srobert            (D->getLinkageAndVisibility().getVisibility() ==
843*12c85518Srobert             DefaultVisibility) &&
844*12c85518Srobert            (getLangOpts().isAllDefaultVisibilityExportMapping() ||
845*12c85518Srobert             (getLangOpts().isExplicitDefaultVisibilityExportMapping() &&
846*12c85518Srobert              D->getLinkageAndVisibility().isVisibilityExplicit()));
847*12c85518Srobert   }
848e5dd7070Spatrick   void setDLLImportDLLExport(llvm::GlobalValue *GV, GlobalDecl D) const;
849e5dd7070Spatrick   void setDLLImportDLLExport(llvm::GlobalValue *GV, const NamedDecl *D) const;
850e5dd7070Spatrick   /// Set visibility, dllimport/dllexport and dso_local.
851e5dd7070Spatrick   /// This must be called after dllimport/dllexport is set.
852e5dd7070Spatrick   void setGVProperties(llvm::GlobalValue *GV, GlobalDecl GD) const;
853e5dd7070Spatrick   void setGVProperties(llvm::GlobalValue *GV, const NamedDecl *D) const;
854e5dd7070Spatrick 
855e5dd7070Spatrick   void setGVPropertiesAux(llvm::GlobalValue *GV, const NamedDecl *D) const;
856e5dd7070Spatrick 
857e5dd7070Spatrick   /// Set the TLS mode for the given LLVM GlobalValue for the thread-local
858e5dd7070Spatrick   /// variable declaration D.
859e5dd7070Spatrick   void setTLSMode(llvm::GlobalValue *GV, const VarDecl &D) const;
860e5dd7070Spatrick 
861ec727ea7Spatrick   /// Get LLVM TLS mode from CodeGenOptions.
862ec727ea7Spatrick   llvm::GlobalVariable::ThreadLocalMode GetDefaultLLVMTLSModel() const;
863ec727ea7Spatrick 
GetLLVMVisibility(Visibility V)864e5dd7070Spatrick   static llvm::GlobalValue::VisibilityTypes GetLLVMVisibility(Visibility V) {
865e5dd7070Spatrick     switch (V) {
866e5dd7070Spatrick     case DefaultVisibility:   return llvm::GlobalValue::DefaultVisibility;
867e5dd7070Spatrick     case HiddenVisibility:    return llvm::GlobalValue::HiddenVisibility;
868e5dd7070Spatrick     case ProtectedVisibility: return llvm::GlobalValue::ProtectedVisibility;
869e5dd7070Spatrick     }
870e5dd7070Spatrick     llvm_unreachable("unknown visibility!");
871e5dd7070Spatrick   }
872e5dd7070Spatrick 
873e5dd7070Spatrick   llvm::Constant *GetAddrOfGlobal(GlobalDecl GD,
874e5dd7070Spatrick                                   ForDefinition_t IsForDefinition
875e5dd7070Spatrick                                     = NotForDefinition);
876e5dd7070Spatrick 
877e5dd7070Spatrick   /// Will return a global variable of the given type. If a variable with a
878e5dd7070Spatrick   /// different type already exists then a new  variable with the right type
879e5dd7070Spatrick   /// will be created and all uses of the old variable will be replaced with a
880e5dd7070Spatrick   /// bitcast to the new variable.
881e5dd7070Spatrick   llvm::GlobalVariable *
882e5dd7070Spatrick   CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty,
883e5dd7070Spatrick                                     llvm::GlobalValue::LinkageTypes Linkage,
884*12c85518Srobert                                     llvm::Align Alignment);
885e5dd7070Spatrick 
886ec727ea7Spatrick   llvm::Function *CreateGlobalInitOrCleanUpFunction(
887ec727ea7Spatrick       llvm::FunctionType *ty, const Twine &name, const CGFunctionInfo &FI,
888*12c85518Srobert       SourceLocation Loc = SourceLocation(), bool TLS = false,
889*12c85518Srobert       llvm::GlobalVariable::LinkageTypes Linkage =
890*12c85518Srobert           llvm::GlobalVariable::InternalLinkage);
891e5dd7070Spatrick 
892e5dd7070Spatrick   /// Return the AST address space of the underlying global variable for D, as
893e5dd7070Spatrick   /// determined by its declaration. Normally this is the same as the address
894e5dd7070Spatrick   /// space of D's type, but in CUDA, address spaces are associated with
895e5dd7070Spatrick   /// declarations, not types. If D is nullptr, return the default address
896e5dd7070Spatrick   /// space for global variable.
897e5dd7070Spatrick   ///
898e5dd7070Spatrick   /// For languages without explicit address spaces, if D has default address
899e5dd7070Spatrick   /// space, target-specific global or constant address space may be returned.
900e5dd7070Spatrick   LangAS GetGlobalVarAddressSpace(const VarDecl *D);
901e5dd7070Spatrick 
902a9ac8606Spatrick   /// Return the AST address space of constant literal, which is used to emit
903a9ac8606Spatrick   /// the constant literal as global variable in LLVM IR.
904a9ac8606Spatrick   /// Note: This is not necessarily the address space of the constant literal
905a9ac8606Spatrick   /// in AST. For address space agnostic language, e.g. C++, constant literal
906a9ac8606Spatrick   /// in AST is always in default address space.
907a9ac8606Spatrick   LangAS GetGlobalConstantAddressSpace() const;
908a9ac8606Spatrick 
909e5dd7070Spatrick   /// Return the llvm::Constant for the address of the given global variable.
910e5dd7070Spatrick   /// If Ty is non-null and if the global doesn't exist, then it will be created
911e5dd7070Spatrick   /// with the specified type instead of whatever the normal requested type
912e5dd7070Spatrick   /// would be. If IsForDefinition is true, it is guaranteed that an actual
913e5dd7070Spatrick   /// global with type Ty will be returned, not conversion of a variable with
914e5dd7070Spatrick   /// the same mangled name but some other type.
915e5dd7070Spatrick   llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D,
916e5dd7070Spatrick                                      llvm::Type *Ty = nullptr,
917e5dd7070Spatrick                                      ForDefinition_t IsForDefinition
918e5dd7070Spatrick                                        = NotForDefinition);
919e5dd7070Spatrick 
920e5dd7070Spatrick   /// Return the address of the given function. If Ty is non-null, then this
921e5dd7070Spatrick   /// function will use the specified type if it has to create it.
922e5dd7070Spatrick   llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = nullptr,
923e5dd7070Spatrick                                     bool ForVTable = false,
924e5dd7070Spatrick                                     bool DontDefer = false,
925e5dd7070Spatrick                                     ForDefinition_t IsForDefinition
926e5dd7070Spatrick                                       = NotForDefinition);
927e5dd7070Spatrick 
928*12c85518Srobert   // Return the function body address of the given function.
929*12c85518Srobert   llvm::Constant *GetFunctionStart(const ValueDecl *Decl);
930*12c85518Srobert 
931e5dd7070Spatrick   /// Get the address of the RTTI descriptor for the given type.
932e5dd7070Spatrick   llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty, bool ForEH = false);
933e5dd7070Spatrick 
934ec727ea7Spatrick   /// Get the address of a GUID.
935ec727ea7Spatrick   ConstantAddress GetAddrOfMSGuidDecl(const MSGuidDecl *GD);
936e5dd7070Spatrick 
937*12c85518Srobert   /// Get the address of a UnnamedGlobalConstant
938*12c85518Srobert   ConstantAddress
939*12c85518Srobert   GetAddrOfUnnamedGlobalConstantDecl(const UnnamedGlobalConstantDecl *GCD);
940*12c85518Srobert 
941a9ac8606Spatrick   /// Get the address of a template parameter object.
942a9ac8606Spatrick   ConstantAddress
943a9ac8606Spatrick   GetAddrOfTemplateParamObject(const TemplateParamObjectDecl *TPO);
944a9ac8606Spatrick 
945e5dd7070Spatrick   /// Get the address of the thunk for the given global decl.
946e5dd7070Spatrick   llvm::Constant *GetAddrOfThunk(StringRef Name, llvm::Type *FnTy,
947e5dd7070Spatrick                                  GlobalDecl GD);
948e5dd7070Spatrick 
949e5dd7070Spatrick   /// Get a reference to the target of VD.
950e5dd7070Spatrick   ConstantAddress GetWeakRefReference(const ValueDecl *VD);
951e5dd7070Spatrick 
952e5dd7070Spatrick   /// Returns the assumed alignment of an opaque pointer to the given class.
953e5dd7070Spatrick   CharUnits getClassPointerAlignment(const CXXRecordDecl *CD);
954e5dd7070Spatrick 
955ec727ea7Spatrick   /// Returns the minimum object size for an object of the given class type
956ec727ea7Spatrick   /// (or a class derived from it).
957ec727ea7Spatrick   CharUnits getMinimumClassObjectSize(const CXXRecordDecl *CD);
958ec727ea7Spatrick 
959ec727ea7Spatrick   /// Returns the minimum object size for an object of the given type.
getMinimumObjectSize(QualType Ty)960ec727ea7Spatrick   CharUnits getMinimumObjectSize(QualType Ty) {
961ec727ea7Spatrick     if (CXXRecordDecl *RD = Ty->getAsCXXRecordDecl())
962ec727ea7Spatrick       return getMinimumClassObjectSize(RD);
963ec727ea7Spatrick     return getContext().getTypeSizeInChars(Ty);
964ec727ea7Spatrick   }
965ec727ea7Spatrick 
966e5dd7070Spatrick   /// Returns the assumed alignment of a virtual base of a class.
967e5dd7070Spatrick   CharUnits getVBaseAlignment(CharUnits DerivedAlign,
968e5dd7070Spatrick                               const CXXRecordDecl *Derived,
969e5dd7070Spatrick                               const CXXRecordDecl *VBase);
970e5dd7070Spatrick 
971e5dd7070Spatrick   /// Given a class pointer with an actual known alignment, and the
972e5dd7070Spatrick   /// expected alignment of an object at a dynamic offset w.r.t that
973e5dd7070Spatrick   /// pointer, return the alignment to assume at the offset.
974e5dd7070Spatrick   CharUnits getDynamicOffsetAlignment(CharUnits ActualAlign,
975e5dd7070Spatrick                                       const CXXRecordDecl *Class,
976e5dd7070Spatrick                                       CharUnits ExpectedTargetAlign);
977e5dd7070Spatrick 
978e5dd7070Spatrick   CharUnits
979e5dd7070Spatrick   computeNonVirtualBaseClassOffset(const CXXRecordDecl *DerivedClass,
980e5dd7070Spatrick                                    CastExpr::path_const_iterator Start,
981e5dd7070Spatrick                                    CastExpr::path_const_iterator End);
982e5dd7070Spatrick 
983e5dd7070Spatrick   /// Returns the offset from a derived class to  a class. Returns null if the
984e5dd7070Spatrick   /// offset is 0.
985e5dd7070Spatrick   llvm::Constant *
986e5dd7070Spatrick   GetNonVirtualBaseClassOffset(const CXXRecordDecl *ClassDecl,
987e5dd7070Spatrick                                CastExpr::path_const_iterator PathBegin,
988e5dd7070Spatrick                                CastExpr::path_const_iterator PathEnd);
989e5dd7070Spatrick 
990e5dd7070Spatrick   llvm::FoldingSet<BlockByrefHelpers> ByrefHelpersCache;
991e5dd7070Spatrick 
992e5dd7070Spatrick   /// Fetches the global unique block count.
getUniqueBlockCount()993e5dd7070Spatrick   int getUniqueBlockCount() { return ++Block.GlobalUniqueCount; }
994e5dd7070Spatrick 
995e5dd7070Spatrick   /// Fetches the type of a generic block descriptor.
996e5dd7070Spatrick   llvm::Type *getBlockDescriptorType();
997e5dd7070Spatrick 
998e5dd7070Spatrick   /// The type of a generic block literal.
999e5dd7070Spatrick   llvm::Type *getGenericBlockLiteralType();
1000e5dd7070Spatrick 
1001e5dd7070Spatrick   /// Gets the address of a block which requires no captures.
1002e5dd7070Spatrick   llvm::Constant *GetAddrOfGlobalBlock(const BlockExpr *BE, StringRef Name);
1003e5dd7070Spatrick 
1004e5dd7070Spatrick   /// Returns the address of a block which requires no caputres, or null if
1005e5dd7070Spatrick   /// we've yet to emit the block for BE.
getAddrOfGlobalBlockIfEmitted(const BlockExpr * BE)1006e5dd7070Spatrick   llvm::Constant *getAddrOfGlobalBlockIfEmitted(const BlockExpr *BE) {
1007e5dd7070Spatrick     return EmittedGlobalBlocks.lookup(BE);
1008e5dd7070Spatrick   }
1009e5dd7070Spatrick 
1010e5dd7070Spatrick   /// Notes that BE's global block is available via Addr. Asserts that BE
1011e5dd7070Spatrick   /// isn't already emitted.
1012e5dd7070Spatrick   void setAddrOfGlobalBlock(const BlockExpr *BE, llvm::Constant *Addr);
1013e5dd7070Spatrick 
1014e5dd7070Spatrick   /// Return a pointer to a constant CFString object for the given string.
1015e5dd7070Spatrick   ConstantAddress GetAddrOfConstantCFString(const StringLiteral *Literal);
1016e5dd7070Spatrick 
1017e5dd7070Spatrick   /// Return a pointer to a constant NSString object for the given string. Or a
1018e5dd7070Spatrick   /// user defined String object as defined via
1019e5dd7070Spatrick   /// -fconstant-string-class=class_name option.
1020e5dd7070Spatrick   ConstantAddress GetAddrOfConstantString(const StringLiteral *Literal);
1021e5dd7070Spatrick 
1022e5dd7070Spatrick   /// Return a constant array for the given string.
1023e5dd7070Spatrick   llvm::Constant *GetConstantArrayFromStringLiteral(const StringLiteral *E);
1024e5dd7070Spatrick 
1025e5dd7070Spatrick   /// Return a pointer to a constant array for the given string literal.
1026e5dd7070Spatrick   ConstantAddress
1027e5dd7070Spatrick   GetAddrOfConstantStringFromLiteral(const StringLiteral *S,
1028e5dd7070Spatrick                                      StringRef Name = ".str");
1029e5dd7070Spatrick 
1030e5dd7070Spatrick   /// Return a pointer to a constant array for the given ObjCEncodeExpr node.
1031e5dd7070Spatrick   ConstantAddress
1032e5dd7070Spatrick   GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *);
1033e5dd7070Spatrick 
1034e5dd7070Spatrick   /// Returns a pointer to a character array containing the literal and a
1035e5dd7070Spatrick   /// terminating '\0' character. The result has pointer to array type.
1036e5dd7070Spatrick   ///
1037e5dd7070Spatrick   /// \param GlobalName If provided, the name to use for the global (if one is
1038e5dd7070Spatrick   /// created).
1039e5dd7070Spatrick   ConstantAddress
1040e5dd7070Spatrick   GetAddrOfConstantCString(const std::string &Str,
1041e5dd7070Spatrick                            const char *GlobalName = nullptr);
1042e5dd7070Spatrick 
1043e5dd7070Spatrick   /// Returns a pointer to a constant global variable for the given file-scope
1044e5dd7070Spatrick   /// compound literal expression.
1045e5dd7070Spatrick   ConstantAddress GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr*E);
1046e5dd7070Spatrick 
1047e5dd7070Spatrick   /// If it's been emitted already, returns the GlobalVariable corresponding to
1048e5dd7070Spatrick   /// a compound literal. Otherwise, returns null.
1049e5dd7070Spatrick   llvm::GlobalVariable *
1050e5dd7070Spatrick   getAddrOfConstantCompoundLiteralIfEmitted(const CompoundLiteralExpr *E);
1051e5dd7070Spatrick 
1052e5dd7070Spatrick   /// Notes that CLE's GlobalVariable is GV. Asserts that CLE isn't already
1053e5dd7070Spatrick   /// emitted.
1054e5dd7070Spatrick   void setAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *CLE,
1055e5dd7070Spatrick                                         llvm::GlobalVariable *GV);
1056e5dd7070Spatrick 
1057e5dd7070Spatrick   /// Returns a pointer to a global variable representing a temporary
1058e5dd7070Spatrick   /// with static or thread storage duration.
1059e5dd7070Spatrick   ConstantAddress GetAddrOfGlobalTemporary(const MaterializeTemporaryExpr *E,
1060e5dd7070Spatrick                                            const Expr *Inner);
1061e5dd7070Spatrick 
1062e5dd7070Spatrick   /// Retrieve the record type that describes the state of an
1063e5dd7070Spatrick   /// Objective-C fast enumeration loop (for..in).
1064e5dd7070Spatrick   QualType getObjCFastEnumerationStateType();
1065e5dd7070Spatrick 
1066e5dd7070Spatrick   // Produce code for this constructor/destructor. This method doesn't try
1067e5dd7070Spatrick   // to apply any ABI rules about which other constructors/destructors
1068e5dd7070Spatrick   // are needed or if they are alias to each other.
1069e5dd7070Spatrick   llvm::Function *codegenCXXStructor(GlobalDecl GD);
1070e5dd7070Spatrick 
1071e5dd7070Spatrick   /// Return the address of the constructor/destructor of the given type.
1072e5dd7070Spatrick   llvm::Constant *
1073e5dd7070Spatrick   getAddrOfCXXStructor(GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr,
1074e5dd7070Spatrick                        llvm::FunctionType *FnType = nullptr,
1075e5dd7070Spatrick                        bool DontDefer = false,
1076e5dd7070Spatrick                        ForDefinition_t IsForDefinition = NotForDefinition) {
1077e5dd7070Spatrick     return cast<llvm::Constant>(getAddrAndTypeOfCXXStructor(GD, FnInfo, FnType,
1078e5dd7070Spatrick                                                             DontDefer,
1079e5dd7070Spatrick                                                             IsForDefinition)
1080e5dd7070Spatrick                                     .getCallee());
1081e5dd7070Spatrick   }
1082e5dd7070Spatrick 
1083e5dd7070Spatrick   llvm::FunctionCallee getAddrAndTypeOfCXXStructor(
1084e5dd7070Spatrick       GlobalDecl GD, const CGFunctionInfo *FnInfo = nullptr,
1085e5dd7070Spatrick       llvm::FunctionType *FnType = nullptr, bool DontDefer = false,
1086e5dd7070Spatrick       ForDefinition_t IsForDefinition = NotForDefinition);
1087e5dd7070Spatrick 
1088e5dd7070Spatrick   /// Given a builtin id for a function like "__builtin_fabsf", return a
1089e5dd7070Spatrick   /// Function* for "fabsf".
1090e5dd7070Spatrick   llvm::Constant *getBuiltinLibFunction(const FunctionDecl *FD,
1091e5dd7070Spatrick                                         unsigned BuiltinID);
1092e5dd7070Spatrick 
1093*12c85518Srobert   llvm::Function *getIntrinsic(unsigned IID,
1094*12c85518Srobert                                ArrayRef<llvm::Type *> Tys = std::nullopt);
1095e5dd7070Spatrick 
1096e5dd7070Spatrick   /// Emit code for a single top level declaration.
1097e5dd7070Spatrick   void EmitTopLevelDecl(Decl *D);
1098e5dd7070Spatrick 
1099e5dd7070Spatrick   /// Stored a deferred empty coverage mapping for an unused
1100e5dd7070Spatrick   /// and thus uninstrumented top level declaration.
1101e5dd7070Spatrick   void AddDeferredUnusedCoverageMapping(Decl *D);
1102e5dd7070Spatrick 
1103e5dd7070Spatrick   /// Remove the deferred empty coverage mapping as this
1104e5dd7070Spatrick   /// declaration is actually instrumented.
1105e5dd7070Spatrick   void ClearUnusedCoverageMapping(const Decl *D);
1106e5dd7070Spatrick 
1107e5dd7070Spatrick   /// Emit all the deferred coverage mappings
1108e5dd7070Spatrick   /// for the uninstrumented functions.
1109e5dd7070Spatrick   void EmitDeferredUnusedCoverageMappings();
1110e5dd7070Spatrick 
1111ec727ea7Spatrick   /// Emit an alias for "main" if it has no arguments (needed for wasm).
1112ec727ea7Spatrick   void EmitMainVoidAlias();
1113ec727ea7Spatrick 
1114e5dd7070Spatrick   /// Tell the consumer that this variable has been instantiated.
1115e5dd7070Spatrick   void HandleCXXStaticMemberVarInstantiation(VarDecl *VD);
1116e5dd7070Spatrick 
1117e5dd7070Spatrick   /// If the declaration has internal linkage but is inside an
1118e5dd7070Spatrick   /// extern "C" linkage specification, prepare to emit an alias for it
1119e5dd7070Spatrick   /// to the expected name.
1120e5dd7070Spatrick   template<typename SomeDecl>
1121e5dd7070Spatrick   void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV);
1122e5dd7070Spatrick 
1123e5dd7070Spatrick   /// Add a global to a list to be added to the llvm.used metadata.
1124e5dd7070Spatrick   void addUsedGlobal(llvm::GlobalValue *GV);
1125e5dd7070Spatrick 
1126e5dd7070Spatrick   /// Add a global to a list to be added to the llvm.compiler.used metadata.
1127e5dd7070Spatrick   void addCompilerUsedGlobal(llvm::GlobalValue *GV);
1128e5dd7070Spatrick 
1129a9ac8606Spatrick   /// Add a global to a list to be added to the llvm.compiler.used metadata.
1130a9ac8606Spatrick   void addUsedOrCompilerUsedGlobal(llvm::GlobalValue *GV);
1131a9ac8606Spatrick 
1132e5dd7070Spatrick   /// Add a destructor and object to add to the C++ global destructor function.
AddCXXDtorEntry(llvm::FunctionCallee DtorFn,llvm::Constant * Object)1133e5dd7070Spatrick   void AddCXXDtorEntry(llvm::FunctionCallee DtorFn, llvm::Constant *Object) {
1134ec727ea7Spatrick     CXXGlobalDtorsOrStermFinalizers.emplace_back(DtorFn.getFunctionType(),
1135ec727ea7Spatrick                                                  DtorFn.getCallee(), Object);
1136ec727ea7Spatrick   }
1137ec727ea7Spatrick 
1138ec727ea7Spatrick   /// Add an sterm finalizer to the C++ global cleanup function.
AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn)1139ec727ea7Spatrick   void AddCXXStermFinalizerEntry(llvm::FunctionCallee DtorFn) {
1140ec727ea7Spatrick     CXXGlobalDtorsOrStermFinalizers.emplace_back(DtorFn.getFunctionType(),
1141ec727ea7Spatrick                                                  DtorFn.getCallee(), nullptr);
1142e5dd7070Spatrick   }
1143e5dd7070Spatrick 
1144a9ac8606Spatrick   /// Add an sterm finalizer to its own llvm.global_dtors entry.
AddCXXStermFinalizerToGlobalDtor(llvm::Function * StermFinalizer,int Priority)1145a9ac8606Spatrick   void AddCXXStermFinalizerToGlobalDtor(llvm::Function *StermFinalizer,
1146a9ac8606Spatrick                                         int Priority) {
1147a9ac8606Spatrick     AddGlobalDtor(StermFinalizer, Priority);
1148a9ac8606Spatrick   }
1149a9ac8606Spatrick 
AddCXXPrioritizedStermFinalizerEntry(llvm::Function * StermFinalizer,int Priority)1150a9ac8606Spatrick   void AddCXXPrioritizedStermFinalizerEntry(llvm::Function *StermFinalizer,
1151a9ac8606Spatrick                                             int Priority) {
1152a9ac8606Spatrick     OrderGlobalInitsOrStermFinalizers Key(Priority,
1153a9ac8606Spatrick                                           PrioritizedCXXStermFinalizers.size());
1154a9ac8606Spatrick     PrioritizedCXXStermFinalizers.push_back(
1155a9ac8606Spatrick         std::make_pair(Key, StermFinalizer));
1156a9ac8606Spatrick   }
1157a9ac8606Spatrick 
1158e5dd7070Spatrick   /// Create or return a runtime function declaration with the specified type
1159e5dd7070Spatrick   /// and name. If \p AssumeConvergent is true, the call will have the
1160e5dd7070Spatrick   /// convergent attribute added.
1161e5dd7070Spatrick   llvm::FunctionCallee
1162e5dd7070Spatrick   CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name,
1163e5dd7070Spatrick                         llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
1164e5dd7070Spatrick                         bool Local = false, bool AssumeConvergent = false);
1165e5dd7070Spatrick 
1166e5dd7070Spatrick   /// Create a new runtime global variable with the specified type and name.
1167e5dd7070Spatrick   llvm::Constant *CreateRuntimeVariable(llvm::Type *Ty,
1168e5dd7070Spatrick                                         StringRef Name);
1169e5dd7070Spatrick 
1170e5dd7070Spatrick   ///@name Custom Blocks Runtime Interfaces
1171e5dd7070Spatrick   ///@{
1172e5dd7070Spatrick 
1173e5dd7070Spatrick   llvm::Constant *getNSConcreteGlobalBlock();
1174e5dd7070Spatrick   llvm::Constant *getNSConcreteStackBlock();
1175e5dd7070Spatrick   llvm::FunctionCallee getBlockObjectAssign();
1176e5dd7070Spatrick   llvm::FunctionCallee getBlockObjectDispose();
1177e5dd7070Spatrick 
1178e5dd7070Spatrick   ///@}
1179e5dd7070Spatrick 
1180e5dd7070Spatrick   llvm::Function *getLLVMLifetimeStartFn();
1181e5dd7070Spatrick   llvm::Function *getLLVMLifetimeEndFn();
1182e5dd7070Spatrick 
1183e5dd7070Spatrick   // Make sure that this type is translated.
1184e5dd7070Spatrick   void UpdateCompletedType(const TagDecl *TD);
1185e5dd7070Spatrick 
1186e5dd7070Spatrick   llvm::Constant *getMemberPointerConstant(const UnaryOperator *e);
1187e5dd7070Spatrick 
1188e5dd7070Spatrick   /// Emit type info if type of an expression is a variably modified
1189e5dd7070Spatrick   /// type. Also emit proper debug info for cast types.
1190e5dd7070Spatrick   void EmitExplicitCastExprType(const ExplicitCastExpr *E,
1191e5dd7070Spatrick                                 CodeGenFunction *CGF = nullptr);
1192e5dd7070Spatrick 
1193e5dd7070Spatrick   /// Return the result of value-initializing the given type, i.e. a null
1194e5dd7070Spatrick   /// expression of the given type.  This is usually, but not always, an LLVM
1195e5dd7070Spatrick   /// null constant.
1196e5dd7070Spatrick   llvm::Constant *EmitNullConstant(QualType T);
1197e5dd7070Spatrick 
1198e5dd7070Spatrick   /// Return a null constant appropriate for zero-initializing a base class with
1199e5dd7070Spatrick   /// the given type. This is usually, but not always, an LLVM null constant.
1200e5dd7070Spatrick   llvm::Constant *EmitNullConstantForBase(const CXXRecordDecl *Record);
1201e5dd7070Spatrick 
1202e5dd7070Spatrick   /// Emit a general error that something can't be done.
1203e5dd7070Spatrick   void Error(SourceLocation loc, StringRef error);
1204e5dd7070Spatrick 
1205e5dd7070Spatrick   /// Print out an error that codegen doesn't support the specified stmt yet.
1206e5dd7070Spatrick   void ErrorUnsupported(const Stmt *S, const char *Type);
1207e5dd7070Spatrick 
1208e5dd7070Spatrick   /// Print out an error that codegen doesn't support the specified decl yet.
1209e5dd7070Spatrick   void ErrorUnsupported(const Decl *D, const char *Type);
1210e5dd7070Spatrick 
1211e5dd7070Spatrick   /// Set the attributes on the LLVM function for the given decl and function
1212e5dd7070Spatrick   /// info. This applies attributes necessary for handling the ABI as well as
1213e5dd7070Spatrick   /// user specified attributes like section.
1214e5dd7070Spatrick   void SetInternalFunctionAttributes(GlobalDecl GD, llvm::Function *F,
1215e5dd7070Spatrick                                      const CGFunctionInfo &FI);
1216e5dd7070Spatrick 
1217e5dd7070Spatrick   /// Set the LLVM function attributes (sext, zext, etc).
1218e5dd7070Spatrick   void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info,
1219a9ac8606Spatrick                                  llvm::Function *F, bool IsThunk);
1220e5dd7070Spatrick 
1221e5dd7070Spatrick   /// Set the LLVM function attributes which only apply to a function
1222e5dd7070Spatrick   /// definition.
1223e5dd7070Spatrick   void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F);
1224e5dd7070Spatrick 
1225a9ac8606Spatrick   /// Set the LLVM function attributes that represent floating point
1226a9ac8606Spatrick   /// environment.
1227a9ac8606Spatrick   void setLLVMFunctionFEnvAttributes(const FunctionDecl *D, llvm::Function *F);
1228a9ac8606Spatrick 
1229e5dd7070Spatrick   /// Return true iff the given type uses 'sret' when used as a return type.
1230e5dd7070Spatrick   bool ReturnTypeUsesSRet(const CGFunctionInfo &FI);
1231e5dd7070Spatrick 
1232e5dd7070Spatrick   /// Return true iff the given type uses an argument slot when 'sret' is used
1233e5dd7070Spatrick   /// as a return type.
1234e5dd7070Spatrick   bool ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI);
1235e5dd7070Spatrick 
1236e5dd7070Spatrick   /// Return true iff the given type uses 'fpret' when used as a return type.
1237e5dd7070Spatrick   bool ReturnTypeUsesFPRet(QualType ResultType);
1238e5dd7070Spatrick 
1239e5dd7070Spatrick   /// Return true iff the given type uses 'fp2ret' when used as a return type.
1240e5dd7070Spatrick   bool ReturnTypeUsesFP2Ret(QualType ResultType);
1241e5dd7070Spatrick 
1242e5dd7070Spatrick   /// Get the LLVM attributes and calling convention to use for a particular
1243e5dd7070Spatrick   /// function type.
1244e5dd7070Spatrick   ///
1245e5dd7070Spatrick   /// \param Name - The function name.
1246e5dd7070Spatrick   /// \param Info - The function type information.
1247e5dd7070Spatrick   /// \param CalleeInfo - The callee information these attributes are being
1248e5dd7070Spatrick   /// constructed for. If valid, the attributes applied to this decl may
1249e5dd7070Spatrick   /// contribute to the function attributes and calling convention.
1250e5dd7070Spatrick   /// \param Attrs [out] - On return, the attribute list to use.
1251e5dd7070Spatrick   /// \param CallingConv [out] - On return, the LLVM calling convention to use.
1252e5dd7070Spatrick   void ConstructAttributeList(StringRef Name, const CGFunctionInfo &Info,
1253e5dd7070Spatrick                               CGCalleeInfo CalleeInfo,
1254e5dd7070Spatrick                               llvm::AttributeList &Attrs, unsigned &CallingConv,
1255a9ac8606Spatrick                               bool AttrOnCallSite, bool IsThunk);
1256e5dd7070Spatrick 
1257e5dd7070Spatrick   /// Adds attributes to F according to our CodeGenOptions and LangOptions, as
1258e5dd7070Spatrick   /// though we had emitted it ourselves.  We remove any attributes on F that
1259e5dd7070Spatrick   /// conflict with the attributes we add here.
1260e5dd7070Spatrick   ///
1261e5dd7070Spatrick   /// This is useful for adding attrs to bitcode modules that you want to link
1262e5dd7070Spatrick   /// with but don't control, such as CUDA's libdevice.  When linking with such
1263e5dd7070Spatrick   /// a bitcode library, you might want to set e.g. its functions'
1264e5dd7070Spatrick   /// "unsafe-fp-math" attribute to match the attr of the functions you're
1265e5dd7070Spatrick   /// codegen'ing.  Otherwise, LLVM will interpret the bitcode module's lack of
1266e5dd7070Spatrick   /// unsafe-fp-math attrs as tantamount to unsafe-fp-math=false, and then LLVM
1267e5dd7070Spatrick   /// will propagate unsafe-fp-math=false up to every transitive caller of a
1268e5dd7070Spatrick   /// function in the bitcode library!
1269e5dd7070Spatrick   ///
1270e5dd7070Spatrick   /// With the exception of fast-math attrs, this will only make the attributes
1271e5dd7070Spatrick   /// on the function more conservative.  But it's unsafe to call this on a
1272e5dd7070Spatrick   /// function which relies on particular fast-math attributes for correctness.
1273e5dd7070Spatrick   /// It's up to you to ensure that this is safe.
1274ec727ea7Spatrick   void addDefaultFunctionDefinitionAttributes(llvm::Function &F);
1275ec727ea7Spatrick 
1276ec727ea7Spatrick   /// Like the overload taking a `Function &`, but intended specifically
1277ec727ea7Spatrick   /// for frontends that want to build on Clang's target-configuration logic.
1278ec727ea7Spatrick   void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs);
1279e5dd7070Spatrick 
1280e5dd7070Spatrick   StringRef getMangledName(GlobalDecl GD);
1281e5dd7070Spatrick   StringRef getBlockMangledName(GlobalDecl GD, const BlockDecl *BD);
1282*12c85518Srobert   const GlobalDecl getMangledNameDecl(StringRef);
1283e5dd7070Spatrick 
1284e5dd7070Spatrick   void EmitTentativeDefinition(const VarDecl *D);
1285e5dd7070Spatrick 
1286e5dd7070Spatrick   void EmitExternalDeclaration(const VarDecl *D);
1287e5dd7070Spatrick 
1288e5dd7070Spatrick   void EmitVTable(CXXRecordDecl *Class);
1289e5dd7070Spatrick 
1290e5dd7070Spatrick   void RefreshTypeCacheForClass(const CXXRecordDecl *Class);
1291e5dd7070Spatrick 
1292e5dd7070Spatrick   /// Appends Opts to the "llvm.linker.options" metadata value.
1293e5dd7070Spatrick   void AppendLinkerOptions(StringRef Opts);
1294e5dd7070Spatrick 
1295e5dd7070Spatrick   /// Appends a detect mismatch command to the linker options.
1296e5dd7070Spatrick   void AddDetectMismatch(StringRef Name, StringRef Value);
1297e5dd7070Spatrick 
1298e5dd7070Spatrick   /// Appends a dependent lib to the appropriate metadata value.
1299e5dd7070Spatrick   void AddDependentLib(StringRef Lib);
1300e5dd7070Spatrick 
1301e5dd7070Spatrick 
1302e5dd7070Spatrick   llvm::GlobalVariable::LinkageTypes getFunctionLinkage(GlobalDecl GD);
1303e5dd7070Spatrick 
setFunctionLinkage(GlobalDecl GD,llvm::Function * F)1304e5dd7070Spatrick   void setFunctionLinkage(GlobalDecl GD, llvm::Function *F) {
1305e5dd7070Spatrick     F->setLinkage(getFunctionLinkage(GD));
1306e5dd7070Spatrick   }
1307e5dd7070Spatrick 
1308e5dd7070Spatrick   /// Return the appropriate linkage for the vtable, VTT, and type information
1309e5dd7070Spatrick   /// of the given class.
1310e5dd7070Spatrick   llvm::GlobalVariable::LinkageTypes getVTableLinkage(const CXXRecordDecl *RD);
1311e5dd7070Spatrick 
1312e5dd7070Spatrick   /// Return the store size, in character units, of the given LLVM type.
1313e5dd7070Spatrick   CharUnits GetTargetTypeStoreSize(llvm::Type *Ty) const;
1314e5dd7070Spatrick 
1315e5dd7070Spatrick   /// Returns LLVM linkage for a declarator.
1316e5dd7070Spatrick   llvm::GlobalValue::LinkageTypes
1317e5dd7070Spatrick   getLLVMLinkageForDeclarator(const DeclaratorDecl *D, GVALinkage Linkage,
1318e5dd7070Spatrick                               bool IsConstantVariable);
1319e5dd7070Spatrick 
1320e5dd7070Spatrick   /// Returns LLVM linkage for a declarator.
1321e5dd7070Spatrick   llvm::GlobalValue::LinkageTypes
1322e5dd7070Spatrick   getLLVMLinkageVarDefinition(const VarDecl *VD, bool IsConstant);
1323e5dd7070Spatrick 
1324e5dd7070Spatrick   /// Emit all the global annotations.
1325e5dd7070Spatrick   void EmitGlobalAnnotations();
1326e5dd7070Spatrick 
1327e5dd7070Spatrick   /// Emit an annotation string.
1328e5dd7070Spatrick   llvm::Constant *EmitAnnotationString(StringRef Str);
1329e5dd7070Spatrick 
1330e5dd7070Spatrick   /// Emit the annotation's translation unit.
1331e5dd7070Spatrick   llvm::Constant *EmitAnnotationUnit(SourceLocation Loc);
1332e5dd7070Spatrick 
1333e5dd7070Spatrick   /// Emit the annotation line number.
1334e5dd7070Spatrick   llvm::Constant *EmitAnnotationLineNo(SourceLocation L);
1335e5dd7070Spatrick 
1336a9ac8606Spatrick   /// Emit additional args of the annotation.
1337a9ac8606Spatrick   llvm::Constant *EmitAnnotationArgs(const AnnotateAttr *Attr);
1338a9ac8606Spatrick 
1339e5dd7070Spatrick   /// Generate the llvm::ConstantStruct which contains the annotation
1340e5dd7070Spatrick   /// information for a given GlobalValue. The annotation struct is
1341e5dd7070Spatrick   /// {i8 *, i8 *, i8 *, i32}. The first field is a constant expression, the
1342e5dd7070Spatrick   /// GlobalValue being annotated. The second field is the constant string
1343e5dd7070Spatrick   /// created from the AnnotateAttr's annotation. The third field is a constant
1344e5dd7070Spatrick   /// string containing the name of the translation unit. The fourth field is
1345e5dd7070Spatrick   /// the line number in the file of the annotated value declaration.
1346e5dd7070Spatrick   llvm::Constant *EmitAnnotateAttr(llvm::GlobalValue *GV,
1347e5dd7070Spatrick                                    const AnnotateAttr *AA,
1348e5dd7070Spatrick                                    SourceLocation L);
1349e5dd7070Spatrick 
1350e5dd7070Spatrick   /// Add global annotations that are set on D, for the global GV. Those
1351e5dd7070Spatrick   /// annotations are emitted during finalization of the LLVM code.
1352e5dd7070Spatrick   void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
1353e5dd7070Spatrick 
1354a9ac8606Spatrick   bool isInNoSanitizeList(SanitizerMask Kind, llvm::Function *Fn,
1355e5dd7070Spatrick                           SourceLocation Loc) const;
1356e5dd7070Spatrick 
1357*12c85518Srobert   bool isInNoSanitizeList(SanitizerMask Kind, llvm::GlobalVariable *GV,
1358*12c85518Srobert                           SourceLocation Loc, QualType Ty,
1359*12c85518Srobert                           StringRef Category = StringRef()) const;
1360e5dd7070Spatrick 
1361e5dd7070Spatrick   /// Imbue XRay attributes to a function, applying the always/never attribute
1362e5dd7070Spatrick   /// lists in the process. Returns true if we did imbue attributes this way,
1363e5dd7070Spatrick   /// false otherwise.
1364e5dd7070Spatrick   bool imbueXRayAttrs(llvm::Function *Fn, SourceLocation Loc,
1365e5dd7070Spatrick                       StringRef Category = StringRef()) const;
1366e5dd7070Spatrick 
1367*12c85518Srobert   /// \returns true if \p Fn at \p Loc should be excluded from profile
1368*12c85518Srobert   /// instrumentation by the SCL passed by \p -fprofile-list.
1369*12c85518Srobert   ProfileList::ExclusionType
1370*12c85518Srobert   isFunctionBlockedByProfileList(llvm::Function *Fn, SourceLocation Loc) const;
1371*12c85518Srobert 
1372*12c85518Srobert   /// \returns true if \p Fn at \p Loc should be excluded from profile
1373*12c85518Srobert   /// instrumentation.
1374*12c85518Srobert   ProfileList::ExclusionType
1375*12c85518Srobert   isFunctionBlockedFromProfileInstr(llvm::Function *Fn,
1376*12c85518Srobert                                     SourceLocation Loc) const;
1377a9ac8606Spatrick 
getSanitizerMetadata()1378e5dd7070Spatrick   SanitizerMetadata *getSanitizerMetadata() {
1379e5dd7070Spatrick     return SanitizerMD.get();
1380e5dd7070Spatrick   }
1381e5dd7070Spatrick 
addDeferredVTable(const CXXRecordDecl * RD)1382e5dd7070Spatrick   void addDeferredVTable(const CXXRecordDecl *RD) {
1383e5dd7070Spatrick     DeferredVTables.push_back(RD);
1384e5dd7070Spatrick   }
1385e5dd7070Spatrick 
1386e5dd7070Spatrick   /// Emit code for a single global function or var decl. Forward declarations
1387e5dd7070Spatrick   /// are emitted lazily.
1388e5dd7070Spatrick   void EmitGlobal(GlobalDecl D);
1389e5dd7070Spatrick 
1390e5dd7070Spatrick   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
1391e5dd7070Spatrick 
1392e5dd7070Spatrick   llvm::GlobalValue *GetGlobalValue(StringRef Ref);
1393e5dd7070Spatrick 
1394e5dd7070Spatrick   /// Set attributes which are common to any form of a global definition (alias,
1395e5dd7070Spatrick   /// Objective-C method, function, global variable).
1396e5dd7070Spatrick   ///
1397e5dd7070Spatrick   /// NOTE: This should only be called for definitions.
1398e5dd7070Spatrick   void SetCommonAttributes(GlobalDecl GD, llvm::GlobalValue *GV);
1399e5dd7070Spatrick 
1400e5dd7070Spatrick   void addReplacement(StringRef Name, llvm::Constant *C);
1401e5dd7070Spatrick 
1402e5dd7070Spatrick   void addGlobalValReplacement(llvm::GlobalValue *GV, llvm::Constant *C);
1403e5dd7070Spatrick 
1404e5dd7070Spatrick   /// Emit a code for threadprivate directive.
1405e5dd7070Spatrick   /// \param D Threadprivate declaration.
1406e5dd7070Spatrick   void EmitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D);
1407e5dd7070Spatrick 
1408e5dd7070Spatrick   /// Emit a code for declare reduction construct.
1409e5dd7070Spatrick   void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
1410e5dd7070Spatrick                                CodeGenFunction *CGF = nullptr);
1411e5dd7070Spatrick 
1412e5dd7070Spatrick   /// Emit a code for declare mapper construct.
1413e5dd7070Spatrick   void EmitOMPDeclareMapper(const OMPDeclareMapperDecl *D,
1414e5dd7070Spatrick                             CodeGenFunction *CGF = nullptr);
1415e5dd7070Spatrick 
1416e5dd7070Spatrick   /// Emit a code for requires directive.
1417e5dd7070Spatrick   /// \param D Requires declaration
1418e5dd7070Spatrick   void EmitOMPRequiresDecl(const OMPRequiresDecl *D);
1419e5dd7070Spatrick 
1420a9ac8606Spatrick   /// Emit a code for the allocate directive.
1421a9ac8606Spatrick   /// \param D The allocate declaration
1422a9ac8606Spatrick   void EmitOMPAllocateDecl(const OMPAllocateDecl *D);
1423a9ac8606Spatrick 
1424*12c85518Srobert   /// Return the alignment specified in an allocate directive, if present.
1425*12c85518Srobert   std::optional<CharUnits> getOMPAllocateAlignment(const VarDecl *VD);
1426*12c85518Srobert 
1427e5dd7070Spatrick   /// Returns whether the given record has hidden LTO visibility and therefore
1428e5dd7070Spatrick   /// may participate in (single-module) CFI and whole-program vtable
1429e5dd7070Spatrick   /// optimization.
1430e5dd7070Spatrick   bool HasHiddenLTOVisibility(const CXXRecordDecl *RD);
1431e5dd7070Spatrick 
1432*12c85518Srobert   /// Returns whether the given record has public LTO visibility (regardless of
1433*12c85518Srobert   /// -lto-whole-program-visibility) and therefore may not participate in
1434*12c85518Srobert   /// (single-module) CFI and whole-program vtable optimization.
1435*12c85518Srobert   bool AlwaysHasLTOVisibilityPublic(const CXXRecordDecl *RD);
1436ec727ea7Spatrick 
1437e5dd7070Spatrick   /// Returns the vcall visibility of the given type. This is the scope in which
1438e5dd7070Spatrick   /// a virtual function call could be made which ends up being dispatched to a
1439e5dd7070Spatrick   /// member function of this class. This scope can be wider than the visibility
1440e5dd7070Spatrick   /// of the class itself when the class has a more-visible dynamic base class.
1441a9ac8606Spatrick   /// The client should pass in an empty Visited set, which is used to prevent
1442a9ac8606Spatrick   /// redundant recursive processing.
1443e5dd7070Spatrick   llvm::GlobalObject::VCallVisibility
1444a9ac8606Spatrick   GetVCallVisibilityLevel(const CXXRecordDecl *RD,
1445a9ac8606Spatrick                           llvm::DenseSet<const CXXRecordDecl *> &Visited);
1446e5dd7070Spatrick 
1447e5dd7070Spatrick   /// Emit type metadata for the given vtable using the given layout.
1448e5dd7070Spatrick   void EmitVTableTypeMetadata(const CXXRecordDecl *RD,
1449e5dd7070Spatrick                               llvm::GlobalVariable *VTable,
1450e5dd7070Spatrick                               const VTableLayout &VTLayout);
1451e5dd7070Spatrick 
1452*12c85518Srobert   llvm::Type *getVTableComponentType() const;
1453*12c85518Srobert 
1454e5dd7070Spatrick   /// Generate a cross-DSO type identifier for MD.
1455e5dd7070Spatrick   llvm::ConstantInt *CreateCrossDsoCfiTypeId(llvm::Metadata *MD);
1456e5dd7070Spatrick 
1457*12c85518Srobert   /// Generate a KCFI type identifier for T.
1458*12c85518Srobert   llvm::ConstantInt *CreateKCFITypeId(QualType T);
1459*12c85518Srobert 
1460e5dd7070Spatrick   /// Create a metadata identifier for the given type. This may either be an
1461e5dd7070Spatrick   /// MDString (for external identifiers) or a distinct unnamed MDNode (for
1462e5dd7070Spatrick   /// internal identifiers).
1463e5dd7070Spatrick   llvm::Metadata *CreateMetadataIdentifierForType(QualType T);
1464e5dd7070Spatrick 
1465e5dd7070Spatrick   /// Create a metadata identifier that is intended to be used to check virtual
1466e5dd7070Spatrick   /// calls via a member function pointer.
1467e5dd7070Spatrick   llvm::Metadata *CreateMetadataIdentifierForVirtualMemPtrType(QualType T);
1468e5dd7070Spatrick 
1469e5dd7070Spatrick   /// Create a metadata identifier for the generalization of the given type.
1470e5dd7070Spatrick   /// This may either be an MDString (for external identifiers) or a distinct
1471e5dd7070Spatrick   /// unnamed MDNode (for internal identifiers).
1472e5dd7070Spatrick   llvm::Metadata *CreateMetadataIdentifierGeneralized(QualType T);
1473e5dd7070Spatrick 
1474e5dd7070Spatrick   /// Create and attach type metadata to the given function.
1475e5dd7070Spatrick   void CreateFunctionTypeMetadataForIcall(const FunctionDecl *FD,
1476e5dd7070Spatrick                                           llvm::Function *F);
1477e5dd7070Spatrick 
1478*12c85518Srobert   /// Set type metadata to the given function.
1479*12c85518Srobert   void setKCFIType(const FunctionDecl *FD, llvm::Function *F);
1480*12c85518Srobert 
1481*12c85518Srobert   /// Emit KCFI type identifier constants and remove unused identifiers.
1482*12c85518Srobert   void finalizeKCFITypes();
1483*12c85518Srobert 
1484a9ac8606Spatrick   /// Whether this function's return type has no side effects, and thus may
1485a9ac8606Spatrick   /// be trivially discarded if it is unused.
1486*12c85518Srobert   bool MayDropFunctionReturn(const ASTContext &Context,
1487*12c85518Srobert                              QualType ReturnType) const;
1488a9ac8606Spatrick 
1489e5dd7070Spatrick   /// Returns whether this module needs the "all-vtables" type identifier.
1490e5dd7070Spatrick   bool NeedAllVtablesTypeId() const;
1491e5dd7070Spatrick 
1492e5dd7070Spatrick   /// Create and attach type metadata for the given vtable.
1493e5dd7070Spatrick   void AddVTableTypeMetadata(llvm::GlobalVariable *VTable, CharUnits Offset,
1494e5dd7070Spatrick                              const CXXRecordDecl *RD);
1495e5dd7070Spatrick 
1496e5dd7070Spatrick   /// Return a vector of most-base classes for RD. This is used to implement
1497e5dd7070Spatrick   /// control flow integrity checks for member function pointers.
1498e5dd7070Spatrick   ///
1499e5dd7070Spatrick   /// A most-base class of a class C is defined as a recursive base class of C,
1500e5dd7070Spatrick   /// including C itself, that does not have any bases.
1501e5dd7070Spatrick   std::vector<const CXXRecordDecl *>
1502e5dd7070Spatrick   getMostBaseClasses(const CXXRecordDecl *RD);
1503e5dd7070Spatrick 
1504*12c85518Srobert   llvm::GlobalVariable *
1505*12c85518Srobert   GetOrCreateRTTIProxyGlobalVariable(llvm::Constant *Addr);
1506*12c85518Srobert 
1507e5dd7070Spatrick   /// Get the declaration of std::terminate for the platform.
1508e5dd7070Spatrick   llvm::FunctionCallee getTerminateFn();
1509e5dd7070Spatrick 
1510e5dd7070Spatrick   llvm::SanitizerStatReport &getSanStats();
1511e5dd7070Spatrick 
1512e5dd7070Spatrick   llvm::Value *
1513e5dd7070Spatrick   createOpenCLIntToSamplerConversion(const Expr *E, CodeGenFunction &CGF);
1514e5dd7070Spatrick 
1515e5dd7070Spatrick   /// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument
1516e5dd7070Spatrick   /// information in the program executable. The argument information stored
1517e5dd7070Spatrick   /// includes the argument name, its type, the address and access qualifiers
1518e5dd7070Spatrick   /// used. This helper can be used to generate metadata for source code kernel
1519e5dd7070Spatrick   /// function as well as generated implicitly kernels. If a kernel is generated
1520e5dd7070Spatrick   /// implicitly null value has to be passed to the last two parameters,
1521e5dd7070Spatrick   /// otherwise all parameters must have valid non-null values.
1522e5dd7070Spatrick   /// \param FN is a pointer to IR function being generated.
1523e5dd7070Spatrick   /// \param FD is a pointer to function declaration if any.
1524e5dd7070Spatrick   /// \param CGF is a pointer to CodeGenFunction that generates this function.
1525*12c85518Srobert   void GenKernelArgMetadata(llvm::Function *FN,
1526e5dd7070Spatrick                             const FunctionDecl *FD = nullptr,
1527e5dd7070Spatrick                             CodeGenFunction *CGF = nullptr);
1528e5dd7070Spatrick 
1529e5dd7070Spatrick   /// Get target specific null pointer.
1530e5dd7070Spatrick   /// \param T is the LLVM type of the null pointer.
1531e5dd7070Spatrick   /// \param QT is the clang QualType of the null pointer.
1532e5dd7070Spatrick   llvm::Constant *getNullPointer(llvm::PointerType *T, QualType QT);
1533e5dd7070Spatrick 
1534ec727ea7Spatrick   CharUnits getNaturalTypeAlignment(QualType T,
1535ec727ea7Spatrick                                     LValueBaseInfo *BaseInfo = nullptr,
1536ec727ea7Spatrick                                     TBAAAccessInfo *TBAAInfo = nullptr,
1537ec727ea7Spatrick                                     bool forPointeeType = false);
1538ec727ea7Spatrick   CharUnits getNaturalPointeeTypeAlignment(QualType T,
1539ec727ea7Spatrick                                            LValueBaseInfo *BaseInfo = nullptr,
1540ec727ea7Spatrick                                            TBAAAccessInfo *TBAAInfo = nullptr);
1541ec727ea7Spatrick   bool stopAutoInit();
1542ec727ea7Spatrick 
1543*12c85518Srobert   /// Print the postfix for externalized static variable or kernels for single
1544*12c85518Srobert   /// source offloading languages CUDA and HIP. The unique postfix is created
1545*12c85518Srobert   /// using either the CUID argument, or the file's UniqueID and active macros.
1546*12c85518Srobert   /// The fallback method without a CUID requires that the offloading toolchain
1547*12c85518Srobert   /// does not define separate macros via the -cc1 options.
1548*12c85518Srobert   void printPostfixForExternalizedDecl(llvm::raw_ostream &OS,
1549*12c85518Srobert                                        const Decl *D) const;
1550*12c85518Srobert 
1551*12c85518Srobert   /// Move some lazily-emitted states to the NewBuilder. This is especially
1552*12c85518Srobert   /// essential for the incremental parsing environment like Clang Interpreter,
1553*12c85518Srobert   /// because we'll lose all important information after each repl.
1554*12c85518Srobert   void moveLazyEmissionStates(CodeGenModule *NewBuilder);
1555a9ac8606Spatrick 
1556e5dd7070Spatrick private:
1557e5dd7070Spatrick   llvm::Constant *GetOrCreateLLVMFunction(
1558e5dd7070Spatrick       StringRef MangledName, llvm::Type *Ty, GlobalDecl D, bool ForVTable,
1559e5dd7070Spatrick       bool DontDefer = false, bool IsThunk = false,
1560e5dd7070Spatrick       llvm::AttributeList ExtraAttrs = llvm::AttributeList(),
1561e5dd7070Spatrick       ForDefinition_t IsForDefinition = NotForDefinition);
1562e5dd7070Spatrick 
1563*12c85518Srobert   // References to multiversion functions are resolved through an implicitly
1564*12c85518Srobert   // defined resolver function. This function is responsible for creating
1565*12c85518Srobert   // the resolver symbol for the provided declaration. The value returned
1566*12c85518Srobert   // will be for an ifunc (llvm::GlobalIFunc) if the current target supports
1567*12c85518Srobert   // that feature and for a regular function (llvm::GlobalValue) otherwise.
1568*12c85518Srobert   llvm::Constant *GetOrCreateMultiVersionResolver(GlobalDecl GD);
1569*12c85518Srobert 
1570*12c85518Srobert   // In scenarios where a function is not known to be a multiversion function
1571*12c85518Srobert   // until a later declaration, it is sometimes necessary to change the
1572*12c85518Srobert   // previously created mangled name to align with requirements of whatever
1573*12c85518Srobert   // multiversion function kind the function is now known to be. This function
1574*12c85518Srobert   // is responsible for performing such mangled name updates.
1575*12c85518Srobert   void UpdateMultiVersionNames(GlobalDecl GD, const FunctionDecl *FD,
1576*12c85518Srobert                                StringRef &CurName);
1577e5dd7070Spatrick 
1578a9ac8606Spatrick   llvm::Constant *
1579*12c85518Srobert   GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, LangAS AddrSpace,
1580*12c85518Srobert                         const VarDecl *D,
1581a9ac8606Spatrick                         ForDefinition_t IsForDefinition = NotForDefinition);
1582e5dd7070Spatrick 
1583e5dd7070Spatrick   bool GetCPUAndFeaturesAttributes(GlobalDecl GD,
1584e5dd7070Spatrick                                    llvm::AttrBuilder &AttrBuilder);
1585e5dd7070Spatrick   void setNonAliasAttributes(GlobalDecl GD, llvm::GlobalObject *GO);
1586e5dd7070Spatrick 
1587e5dd7070Spatrick   /// Set function attributes for a function declaration.
1588e5dd7070Spatrick   void SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
1589e5dd7070Spatrick                              bool IsIncompleteFunction, bool IsThunk);
1590e5dd7070Spatrick 
1591e5dd7070Spatrick   void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr);
1592e5dd7070Spatrick 
1593e5dd7070Spatrick   void EmitGlobalFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV);
1594e5dd7070Spatrick   void EmitMultiVersionFunctionDefinition(GlobalDecl GD, llvm::GlobalValue *GV);
1595e5dd7070Spatrick 
1596e5dd7070Spatrick   void EmitGlobalVarDefinition(const VarDecl *D, bool IsTentative = false);
1597e5dd7070Spatrick   void EmitExternalVarDeclaration(const VarDecl *D);
1598e5dd7070Spatrick   void EmitAliasDefinition(GlobalDecl GD);
1599e5dd7070Spatrick   void emitIFuncDefinition(GlobalDecl GD);
1600e5dd7070Spatrick   void emitCPUDispatchDefinition(GlobalDecl GD);
1601e5dd7070Spatrick   void EmitObjCPropertyImplementations(const ObjCImplementationDecl *D);
1602e5dd7070Spatrick   void EmitObjCIvarInitializations(ObjCImplementationDecl *D);
1603e5dd7070Spatrick 
1604e5dd7070Spatrick   // C++ related functions.
1605e5dd7070Spatrick 
1606e5dd7070Spatrick   void EmitDeclContext(const DeclContext *DC);
1607e5dd7070Spatrick   void EmitLinkageSpec(const LinkageSpecDecl *D);
1608*12c85518Srobert   void EmitTopLevelStmt(const TopLevelStmtDecl *D);
1609e5dd7070Spatrick 
1610e5dd7070Spatrick   /// Emit the function that initializes C++ thread_local variables.
1611e5dd7070Spatrick   void EmitCXXThreadLocalInitFunc();
1612e5dd7070Spatrick 
1613*12c85518Srobert   /// Emit the function that initializes global variables for a C++ Module.
1614*12c85518Srobert   void EmitCXXModuleInitFunc(clang::Module *Primary);
1615*12c85518Srobert 
1616e5dd7070Spatrick   /// Emit the function that initializes C++ globals.
1617e5dd7070Spatrick   void EmitCXXGlobalInitFunc();
1618e5dd7070Spatrick 
1619ec727ea7Spatrick   /// Emit the function that performs cleanup associated with C++ globals.
1620ec727ea7Spatrick   void EmitCXXGlobalCleanUpFunc();
1621e5dd7070Spatrick 
1622e5dd7070Spatrick   /// Emit the function that initializes the specified global (if PerformInit is
1623e5dd7070Spatrick   /// true) and registers its destructor.
1624e5dd7070Spatrick   void EmitCXXGlobalVarDeclInitFunc(const VarDecl *D,
1625e5dd7070Spatrick                                     llvm::GlobalVariable *Addr,
1626e5dd7070Spatrick                                     bool PerformInit);
1627e5dd7070Spatrick 
1628e5dd7070Spatrick   void EmitPointerToInitFunc(const VarDecl *VD, llvm::GlobalVariable *Addr,
1629e5dd7070Spatrick                              llvm::Function *InitFunc, InitSegAttr *ISA);
1630e5dd7070Spatrick 
1631e5dd7070Spatrick   // FIXME: Hardcoding priority here is gross.
1632e5dd7070Spatrick   void AddGlobalCtor(llvm::Function *Ctor, int Priority = 65535,
1633*12c85518Srobert                      unsigned LexOrder = ~0U,
1634e5dd7070Spatrick                      llvm::Constant *AssociatedData = nullptr);
1635a9ac8606Spatrick   void AddGlobalDtor(llvm::Function *Dtor, int Priority = 65535,
1636a9ac8606Spatrick                      bool IsDtorAttrFunc = false);
1637e5dd7070Spatrick 
1638e5dd7070Spatrick   /// EmitCtorList - Generates a global array of functions and priorities using
1639e5dd7070Spatrick   /// the given list and name. This array will have appending linkage and is
1640e5dd7070Spatrick   /// suitable for use as a LLVM constructor or destructor array. Clears Fns.
1641e5dd7070Spatrick   void EmitCtorList(CtorList &Fns, const char *GlobalName);
1642e5dd7070Spatrick 
1643e5dd7070Spatrick   /// Emit any needed decls for which code generation was deferred.
1644e5dd7070Spatrick   void EmitDeferred();
1645e5dd7070Spatrick 
1646e5dd7070Spatrick   /// Try to emit external vtables as available_externally if they have emitted
1647e5dd7070Spatrick   /// all inlined virtual functions.  It runs after EmitDeferred() and therefore
1648e5dd7070Spatrick   /// is not allowed to create new references to things that need to be emitted
1649e5dd7070Spatrick   /// lazily.
1650e5dd7070Spatrick   void EmitVTablesOpportunistically();
1651e5dd7070Spatrick 
1652e5dd7070Spatrick   /// Call replaceAllUsesWith on all pairs in Replacements.
1653e5dd7070Spatrick   void applyReplacements();
1654e5dd7070Spatrick 
1655e5dd7070Spatrick   /// Call replaceAllUsesWith on all pairs in GlobalValReplacements.
1656e5dd7070Spatrick   void applyGlobalValReplacements();
1657e5dd7070Spatrick 
1658e5dd7070Spatrick   void checkAliases();
1659e5dd7070Spatrick 
1660e5dd7070Spatrick   std::map<int, llvm::TinyPtrVector<llvm::Function *>> DtorsUsingAtExit;
1661e5dd7070Spatrick 
1662e5dd7070Spatrick   /// Register functions annotated with __attribute__((destructor)) using
1663e5dd7070Spatrick   /// __cxa_atexit, if it is available, or atexit otherwise.
1664e5dd7070Spatrick   void registerGlobalDtorsWithAtExit();
1665e5dd7070Spatrick 
1666a9ac8606Spatrick   // When using sinit and sterm functions, unregister
1667a9ac8606Spatrick   // __attribute__((destructor)) annotated functions which were previously
1668a9ac8606Spatrick   // registered by the atexit subroutine using unatexit.
1669a9ac8606Spatrick   void unregisterGlobalDtorsWithUnAtExit();
1670a9ac8606Spatrick 
1671*12c85518Srobert   /// Emit deferred multiversion function resolvers and associated variants.
1672e5dd7070Spatrick   void emitMultiVersionFunctions();
1673e5dd7070Spatrick 
1674e5dd7070Spatrick   /// Emit any vtables which we deferred and still have a use for.
1675e5dd7070Spatrick   void EmitDeferredVTables();
1676e5dd7070Spatrick 
1677e5dd7070Spatrick   /// Emit a dummy function that reference a CoreFoundation symbol when
1678e5dd7070Spatrick   /// @available is used on Darwin.
1679e5dd7070Spatrick   void emitAtAvailableLinkGuard();
1680e5dd7070Spatrick 
1681e5dd7070Spatrick   /// Emit the llvm.used and llvm.compiler.used metadata.
1682e5dd7070Spatrick   void emitLLVMUsed();
1683e5dd7070Spatrick 
1684*12c85518Srobert   /// For C++20 Itanium ABI, emit the initializers for the module.
1685*12c85518Srobert   void EmitModuleInitializers(clang::Module *Primary);
1686*12c85518Srobert 
1687e5dd7070Spatrick   /// Emit the link options introduced by imported modules.
1688e5dd7070Spatrick   void EmitModuleLinkOptions();
1689e5dd7070Spatrick 
1690*12c85518Srobert   /// Helper function for EmitStaticExternCAliases() to redirect ifuncs that
1691*12c85518Srobert   /// have a resolver name that matches 'Elem' to instead resolve to the name of
1692*12c85518Srobert   /// 'CppFunc'. This redirection is necessary in cases where 'Elem' has a name
1693*12c85518Srobert   /// that will be emitted as an alias of the name bound to 'CppFunc'; ifuncs
1694*12c85518Srobert   /// may not reference aliases. Redirection is only performed if 'Elem' is only
1695*12c85518Srobert   /// used by ifuncs in which case, 'Elem' is destroyed. 'true' is returned if
1696*12c85518Srobert   /// redirection is successful, and 'false' is returned otherwise.
1697*12c85518Srobert   bool CheckAndReplaceExternCIFuncs(llvm::GlobalValue *Elem,
1698*12c85518Srobert                                     llvm::GlobalValue *CppFunc);
1699*12c85518Srobert 
1700e5dd7070Spatrick   /// Emit aliases for internal-linkage declarations inside "C" language
1701e5dd7070Spatrick   /// linkage specifications, giving them the "expected" name where possible.
1702e5dd7070Spatrick   void EmitStaticExternCAliases();
1703e5dd7070Spatrick 
1704e5dd7070Spatrick   void EmitDeclMetadata();
1705e5dd7070Spatrick 
1706e5dd7070Spatrick   /// Emit the Clang version as llvm.ident metadata.
1707e5dd7070Spatrick   void EmitVersionIdentMetadata();
1708e5dd7070Spatrick 
1709e5dd7070Spatrick   /// Emit the Clang commandline as llvm.commandline metadata.
1710e5dd7070Spatrick   void EmitCommandLineMetadata();
1711e5dd7070Spatrick 
1712ec727ea7Spatrick   /// Emit the module flag metadata used to pass options controlling the
1713ec727ea7Spatrick   /// the backend to LLVM.
1714ec727ea7Spatrick   void EmitBackendOptionsMetadata(const CodeGenOptions CodeGenOpts);
1715e5dd7070Spatrick 
1716e5dd7070Spatrick   /// Emits OpenCL specific Metadata e.g. OpenCL version.
1717e5dd7070Spatrick   void EmitOpenCLMetadata();
1718e5dd7070Spatrick 
1719e5dd7070Spatrick   /// Emit the llvm.gcov metadata used to tell LLVM where to emit the .gcno and
1720e5dd7070Spatrick   /// .gcda files in a way that persists in .bc files.
1721e5dd7070Spatrick   void EmitCoverageFile();
1722e5dd7070Spatrick 
1723e5dd7070Spatrick   /// Determine whether the definition must be emitted; if this returns \c
1724e5dd7070Spatrick   /// false, the definition can be emitted lazily if it's used.
1725e5dd7070Spatrick   bool MustBeEmitted(const ValueDecl *D);
1726e5dd7070Spatrick 
1727e5dd7070Spatrick   /// Determine whether the definition can be emitted eagerly, or should be
1728e5dd7070Spatrick   /// delayed until the end of the translation unit. This is relevant for
1729e5dd7070Spatrick   /// definitions whose linkage can change, e.g. implicit function instantions
1730e5dd7070Spatrick   /// which may later be explicitly instantiated.
1731e5dd7070Spatrick   bool MayBeEmittedEagerly(const ValueDecl *D);
1732e5dd7070Spatrick 
1733e5dd7070Spatrick   /// Check whether we can use a "simpler", more core exceptions personality
1734e5dd7070Spatrick   /// function.
1735e5dd7070Spatrick   void SimplifyPersonality();
1736e5dd7070Spatrick 
1737ec727ea7Spatrick   /// Helper function for ConstructAttributeList and
1738ec727ea7Spatrick   /// addDefaultFunctionDefinitionAttributes.  Builds a set of function
1739ec727ea7Spatrick   /// attributes to add to a function with the given properties.
1740ec727ea7Spatrick   void getDefaultFunctionAttributes(StringRef Name, bool HasOptnone,
1741e5dd7070Spatrick                                     bool AttrOnCallSite,
1742e5dd7070Spatrick                                     llvm::AttrBuilder &FuncAttrs);
1743e5dd7070Spatrick 
1744e5dd7070Spatrick   llvm::Metadata *CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map,
1745e5dd7070Spatrick                                                StringRef Suffix);
1746e5dd7070Spatrick };
1747e5dd7070Spatrick 
1748e5dd7070Spatrick }  // end namespace CodeGen
1749e5dd7070Spatrick }  // end namespace clang
1750e5dd7070Spatrick 
1751e5dd7070Spatrick #endif // LLVM_CLANG_LIB_CODEGEN_CODEGENMODULE_H
1752