1e5dd7070Spatrick //===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
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 builds an AST and converts it to LLVM Code.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick
13e5dd7070Spatrick #include "clang/CodeGen/ModuleBuilder.h"
14e5dd7070Spatrick #include "CGDebugInfo.h"
15e5dd7070Spatrick #include "CodeGenModule.h"
16e5dd7070Spatrick #include "clang/AST/ASTContext.h"
17e5dd7070Spatrick #include "clang/AST/DeclObjC.h"
18e5dd7070Spatrick #include "clang/AST/Expr.h"
19e5dd7070Spatrick #include "clang/Basic/CodeGenOptions.h"
20e5dd7070Spatrick #include "clang/Basic/Diagnostic.h"
21e5dd7070Spatrick #include "clang/Basic/TargetInfo.h"
22e5dd7070Spatrick #include "llvm/ADT/StringRef.h"
23e5dd7070Spatrick #include "llvm/IR/DataLayout.h"
24e5dd7070Spatrick #include "llvm/IR/LLVMContext.h"
25e5dd7070Spatrick #include "llvm/IR/Module.h"
26*12c85518Srobert #include "llvm/Support/VirtualFileSystem.h"
27e5dd7070Spatrick #include <memory>
28e5dd7070Spatrick
29e5dd7070Spatrick using namespace clang;
30e5dd7070Spatrick using namespace CodeGen;
31e5dd7070Spatrick
32e5dd7070Spatrick namespace {
33e5dd7070Spatrick class CodeGeneratorImpl : public CodeGenerator {
34e5dd7070Spatrick DiagnosticsEngine &Diags;
35e5dd7070Spatrick ASTContext *Ctx;
36*12c85518Srobert IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; // Only used for debug info.
37e5dd7070Spatrick const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info.
38e5dd7070Spatrick const PreprocessorOptions &PreprocessorOpts; // Only used for debug info.
39e5dd7070Spatrick const CodeGenOptions CodeGenOpts; // Intentionally copied in.
40e5dd7070Spatrick
41e5dd7070Spatrick unsigned HandlingTopLevelDecls;
42e5dd7070Spatrick
43e5dd7070Spatrick /// Use this when emitting decls to block re-entrant decl emission. It will
44e5dd7070Spatrick /// emit all deferred decls on scope exit. Set EmitDeferred to false if decl
45e5dd7070Spatrick /// emission must be deferred longer, like at the end of a tag definition.
46e5dd7070Spatrick struct HandlingTopLevelDeclRAII {
47e5dd7070Spatrick CodeGeneratorImpl &Self;
48e5dd7070Spatrick bool EmitDeferred;
HandlingTopLevelDeclRAII__anon2a1548e20111::CodeGeneratorImpl::HandlingTopLevelDeclRAII49e5dd7070Spatrick HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
50e5dd7070Spatrick bool EmitDeferred = true)
51e5dd7070Spatrick : Self(Self), EmitDeferred(EmitDeferred) {
52e5dd7070Spatrick ++Self.HandlingTopLevelDecls;
53e5dd7070Spatrick }
~HandlingTopLevelDeclRAII__anon2a1548e20111::CodeGeneratorImpl::HandlingTopLevelDeclRAII54e5dd7070Spatrick ~HandlingTopLevelDeclRAII() {
55e5dd7070Spatrick unsigned Level = --Self.HandlingTopLevelDecls;
56e5dd7070Spatrick if (Level == 0 && EmitDeferred)
57e5dd7070Spatrick Self.EmitDeferredDecls();
58e5dd7070Spatrick }
59e5dd7070Spatrick };
60e5dd7070Spatrick
61e5dd7070Spatrick CoverageSourceInfo *CoverageInfo;
62e5dd7070Spatrick
63e5dd7070Spatrick protected:
64e5dd7070Spatrick std::unique_ptr<llvm::Module> M;
65e5dd7070Spatrick std::unique_ptr<CodeGen::CodeGenModule> Builder;
66e5dd7070Spatrick
67e5dd7070Spatrick private:
68e5dd7070Spatrick SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
69e5dd7070Spatrick
ExpandModuleName(llvm::StringRef ModuleName,const CodeGenOptions & CGO)70e5dd7070Spatrick static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
71e5dd7070Spatrick const CodeGenOptions &CGO) {
72e5dd7070Spatrick if (ModuleName == "-" && !CGO.MainFileName.empty())
73e5dd7070Spatrick return CGO.MainFileName;
74e5dd7070Spatrick return ModuleName;
75e5dd7070Spatrick }
76e5dd7070Spatrick
77e5dd7070Spatrick public:
CodeGeneratorImpl(DiagnosticsEngine & diags,llvm::StringRef ModuleName,IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,const HeaderSearchOptions & HSO,const PreprocessorOptions & PPO,const CodeGenOptions & CGO,llvm::LLVMContext & C,CoverageSourceInfo * CoverageInfo=nullptr)78e5dd7070Spatrick CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
79*12c85518Srobert IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
80e5dd7070Spatrick const HeaderSearchOptions &HSO,
81e5dd7070Spatrick const PreprocessorOptions &PPO, const CodeGenOptions &CGO,
82e5dd7070Spatrick llvm::LLVMContext &C,
83e5dd7070Spatrick CoverageSourceInfo *CoverageInfo = nullptr)
84*12c85518Srobert : Diags(diags), Ctx(nullptr), FS(std::move(FS)), HeaderSearchOpts(HSO),
85e5dd7070Spatrick PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
86e5dd7070Spatrick CoverageInfo(CoverageInfo),
87e5dd7070Spatrick M(new llvm::Module(ExpandModuleName(ModuleName, CGO), C)) {
88e5dd7070Spatrick C.setDiscardValueNames(CGO.DiscardValueNames);
89e5dd7070Spatrick }
90e5dd7070Spatrick
~CodeGeneratorImpl()91e5dd7070Spatrick ~CodeGeneratorImpl() override {
92e5dd7070Spatrick // There should normally not be any leftover inline method definitions.
93e5dd7070Spatrick assert(DeferredInlineMemberFuncDefs.empty() ||
94e5dd7070Spatrick Diags.hasErrorOccurred());
95e5dd7070Spatrick }
96e5dd7070Spatrick
CGM()97e5dd7070Spatrick CodeGenModule &CGM() {
98e5dd7070Spatrick return *Builder;
99e5dd7070Spatrick }
100e5dd7070Spatrick
GetModule()101e5dd7070Spatrick llvm::Module *GetModule() {
102e5dd7070Spatrick return M.get();
103e5dd7070Spatrick }
104e5dd7070Spatrick
getCGDebugInfo()105e5dd7070Spatrick CGDebugInfo *getCGDebugInfo() {
106e5dd7070Spatrick return Builder->getModuleDebugInfo();
107e5dd7070Spatrick }
108e5dd7070Spatrick
ReleaseModule()109e5dd7070Spatrick llvm::Module *ReleaseModule() {
110e5dd7070Spatrick return M.release();
111e5dd7070Spatrick }
112e5dd7070Spatrick
GetDeclForMangledName(StringRef MangledName)113e5dd7070Spatrick const Decl *GetDeclForMangledName(StringRef MangledName) {
114e5dd7070Spatrick GlobalDecl Result;
115e5dd7070Spatrick if (!Builder->lookupRepresentativeDecl(MangledName, Result))
116e5dd7070Spatrick return nullptr;
117e5dd7070Spatrick const Decl *D = Result.getCanonicalDecl().getDecl();
118e5dd7070Spatrick if (auto FD = dyn_cast<FunctionDecl>(D)) {
119e5dd7070Spatrick if (FD->hasBody(FD))
120e5dd7070Spatrick return FD;
121e5dd7070Spatrick } else if (auto TD = dyn_cast<TagDecl>(D)) {
122e5dd7070Spatrick if (auto Def = TD->getDefinition())
123e5dd7070Spatrick return Def;
124e5dd7070Spatrick }
125e5dd7070Spatrick return D;
126e5dd7070Spatrick }
127e5dd7070Spatrick
GetMangledName(GlobalDecl GD)128*12c85518Srobert llvm::StringRef GetMangledName(GlobalDecl GD) {
129*12c85518Srobert return Builder->getMangledName(GD);
130*12c85518Srobert }
131*12c85518Srobert
GetAddrOfGlobal(GlobalDecl global,bool isForDefinition)132e5dd7070Spatrick llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) {
133e5dd7070Spatrick return Builder->GetAddrOfGlobal(global, ForDefinition_t(isForDefinition));
134e5dd7070Spatrick }
135e5dd7070Spatrick
StartModule(llvm::StringRef ModuleName,llvm::LLVMContext & C)136e5dd7070Spatrick llvm::Module *StartModule(llvm::StringRef ModuleName,
137e5dd7070Spatrick llvm::LLVMContext &C) {
138e5dd7070Spatrick assert(!M && "Replacing existing Module?");
139e5dd7070Spatrick M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));
140*12c85518Srobert
141*12c85518Srobert std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
142*12c85518Srobert
143e5dd7070Spatrick Initialize(*Ctx);
144*12c85518Srobert
145*12c85518Srobert if (OldBuilder)
146*12c85518Srobert OldBuilder->moveLazyEmissionStates(Builder.get());
147*12c85518Srobert
148e5dd7070Spatrick return M.get();
149e5dd7070Spatrick }
150e5dd7070Spatrick
Initialize(ASTContext & Context)151e5dd7070Spatrick void Initialize(ASTContext &Context) override {
152e5dd7070Spatrick Ctx = &Context;
153e5dd7070Spatrick
154e5dd7070Spatrick M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
155a9ac8606Spatrick M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
156e5dd7070Spatrick const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion();
157e5dd7070Spatrick if (!SDKVersion.empty())
158e5dd7070Spatrick M->setSDKVersion(SDKVersion);
159*12c85518Srobert if (const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
160*12c85518Srobert M->setDarwinTargetVariantTriple(TVT->getTriple());
161*12c85518Srobert if (auto TVSDKVersion =
162*12c85518Srobert Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
163*12c85518Srobert M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
164*12c85518Srobert Builder.reset(new CodeGen::CodeGenModule(Context, FS, HeaderSearchOpts,
165e5dd7070Spatrick PreprocessorOpts, CodeGenOpts,
166e5dd7070Spatrick *M, Diags, CoverageInfo));
167e5dd7070Spatrick
168e5dd7070Spatrick for (auto &&Lib : CodeGenOpts.DependentLibraries)
169e5dd7070Spatrick Builder->AddDependentLib(Lib);
170e5dd7070Spatrick for (auto &&Opt : CodeGenOpts.LinkerOptions)
171e5dd7070Spatrick Builder->AppendLinkerOptions(Opt);
172e5dd7070Spatrick }
173e5dd7070Spatrick
HandleCXXStaticMemberVarInstantiation(VarDecl * VD)174e5dd7070Spatrick void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
175e5dd7070Spatrick if (Diags.hasErrorOccurred())
176e5dd7070Spatrick return;
177e5dd7070Spatrick
178e5dd7070Spatrick Builder->HandleCXXStaticMemberVarInstantiation(VD);
179e5dd7070Spatrick }
180e5dd7070Spatrick
HandleTopLevelDecl(DeclGroupRef DG)181e5dd7070Spatrick bool HandleTopLevelDecl(DeclGroupRef DG) override {
182*12c85518Srobert // FIXME: Why not return false and abort parsing?
183e5dd7070Spatrick if (Diags.hasErrorOccurred())
184e5dd7070Spatrick return true;
185e5dd7070Spatrick
186e5dd7070Spatrick HandlingTopLevelDeclRAII HandlingDecl(*this);
187e5dd7070Spatrick
188e5dd7070Spatrick // Make sure to emit all elements of a Decl.
189e5dd7070Spatrick for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
190e5dd7070Spatrick Builder->EmitTopLevelDecl(*I);
191e5dd7070Spatrick
192e5dd7070Spatrick return true;
193e5dd7070Spatrick }
194e5dd7070Spatrick
EmitDeferredDecls()195e5dd7070Spatrick void EmitDeferredDecls() {
196e5dd7070Spatrick if (DeferredInlineMemberFuncDefs.empty())
197e5dd7070Spatrick return;
198e5dd7070Spatrick
199e5dd7070Spatrick // Emit any deferred inline method definitions. Note that more deferred
200e5dd7070Spatrick // methods may be added during this loop, since ASTConsumer callbacks
201e5dd7070Spatrick // can be invoked if AST inspection results in declarations being added.
202e5dd7070Spatrick HandlingTopLevelDeclRAII HandlingDecl(*this);
203e5dd7070Spatrick for (unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
204e5dd7070Spatrick Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
205e5dd7070Spatrick DeferredInlineMemberFuncDefs.clear();
206e5dd7070Spatrick }
207e5dd7070Spatrick
HandleInlineFunctionDefinition(FunctionDecl * D)208e5dd7070Spatrick void HandleInlineFunctionDefinition(FunctionDecl *D) override {
209e5dd7070Spatrick if (Diags.hasErrorOccurred())
210e5dd7070Spatrick return;
211e5dd7070Spatrick
212e5dd7070Spatrick assert(D->doesThisDeclarationHaveABody());
213e5dd7070Spatrick
214e5dd7070Spatrick // We may want to emit this definition. However, that decision might be
215e5dd7070Spatrick // based on computing the linkage, and we have to defer that in case we
216e5dd7070Spatrick // are inside of something that will change the method's final linkage,
217e5dd7070Spatrick // e.g.
218e5dd7070Spatrick // typedef struct {
219e5dd7070Spatrick // void bar();
220e5dd7070Spatrick // void foo() { bar(); }
221e5dd7070Spatrick // } A;
222e5dd7070Spatrick DeferredInlineMemberFuncDefs.push_back(D);
223e5dd7070Spatrick
224e5dd7070Spatrick // Provide some coverage mapping even for methods that aren't emitted.
225e5dd7070Spatrick // Don't do this for templated classes though, as they may not be
226e5dd7070Spatrick // instantiable.
227e5dd7070Spatrick if (!D->getLexicalDeclContext()->isDependentContext())
228e5dd7070Spatrick Builder->AddDeferredUnusedCoverageMapping(D);
229e5dd7070Spatrick }
230e5dd7070Spatrick
231e5dd7070Spatrick /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
232e5dd7070Spatrick /// to (e.g. struct, union, enum, class) is completed. This allows the
233e5dd7070Spatrick /// client hack on the type, which can occur at any point in the file
234e5dd7070Spatrick /// (because these can be defined in declspecs).
HandleTagDeclDefinition(TagDecl * D)235e5dd7070Spatrick void HandleTagDeclDefinition(TagDecl *D) override {
236e5dd7070Spatrick if (Diags.hasErrorOccurred())
237e5dd7070Spatrick return;
238e5dd7070Spatrick
239e5dd7070Spatrick // Don't allow re-entrant calls to CodeGen triggered by PCH
240e5dd7070Spatrick // deserialization to emit deferred decls.
241e5dd7070Spatrick HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
242e5dd7070Spatrick
243e5dd7070Spatrick Builder->UpdateCompletedType(D);
244e5dd7070Spatrick
245e5dd7070Spatrick // For MSVC compatibility, treat declarations of static data members with
246e5dd7070Spatrick // inline initializers as definitions.
247e5dd7070Spatrick if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
248e5dd7070Spatrick for (Decl *Member : D->decls()) {
249e5dd7070Spatrick if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
250e5dd7070Spatrick if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
251e5dd7070Spatrick Ctx->DeclMustBeEmitted(VD)) {
252e5dd7070Spatrick Builder->EmitGlobal(VD);
253e5dd7070Spatrick }
254e5dd7070Spatrick }
255e5dd7070Spatrick }
256e5dd7070Spatrick }
257e5dd7070Spatrick // For OpenMP emit declare reduction functions, if required.
258e5dd7070Spatrick if (Ctx->getLangOpts().OpenMP) {
259e5dd7070Spatrick for (Decl *Member : D->decls()) {
260e5dd7070Spatrick if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(Member)) {
261e5dd7070Spatrick if (Ctx->DeclMustBeEmitted(DRD))
262e5dd7070Spatrick Builder->EmitGlobal(DRD);
263e5dd7070Spatrick } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Member)) {
264e5dd7070Spatrick if (Ctx->DeclMustBeEmitted(DMD))
265e5dd7070Spatrick Builder->EmitGlobal(DMD);
266e5dd7070Spatrick }
267e5dd7070Spatrick }
268e5dd7070Spatrick }
269e5dd7070Spatrick }
270e5dd7070Spatrick
HandleTagDeclRequiredDefinition(const TagDecl * D)271e5dd7070Spatrick void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
272e5dd7070Spatrick if (Diags.hasErrorOccurred())
273e5dd7070Spatrick return;
274e5dd7070Spatrick
275e5dd7070Spatrick // Don't allow re-entrant calls to CodeGen triggered by PCH
276e5dd7070Spatrick // deserialization to emit deferred decls.
277e5dd7070Spatrick HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
278e5dd7070Spatrick
279e5dd7070Spatrick if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
280e5dd7070Spatrick if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
281e5dd7070Spatrick DI->completeRequiredType(RD);
282e5dd7070Spatrick }
283e5dd7070Spatrick
HandleTranslationUnit(ASTContext & Ctx)284e5dd7070Spatrick void HandleTranslationUnit(ASTContext &Ctx) override {
285e5dd7070Spatrick // Release the Builder when there is no error.
286e5dd7070Spatrick if (!Diags.hasErrorOccurred() && Builder)
287e5dd7070Spatrick Builder->Release();
288e5dd7070Spatrick
289e5dd7070Spatrick // If there are errors before or when releasing the Builder, reset
290e5dd7070Spatrick // the module to stop here before invoking the backend.
291e5dd7070Spatrick if (Diags.hasErrorOccurred()) {
292e5dd7070Spatrick if (Builder)
293e5dd7070Spatrick Builder->clear();
294e5dd7070Spatrick M.reset();
295e5dd7070Spatrick return;
296e5dd7070Spatrick }
297e5dd7070Spatrick }
298e5dd7070Spatrick
AssignInheritanceModel(CXXRecordDecl * RD)299e5dd7070Spatrick void AssignInheritanceModel(CXXRecordDecl *RD) override {
300e5dd7070Spatrick if (Diags.hasErrorOccurred())
301e5dd7070Spatrick return;
302e5dd7070Spatrick
303e5dd7070Spatrick Builder->RefreshTypeCacheForClass(RD);
304e5dd7070Spatrick }
305e5dd7070Spatrick
CompleteTentativeDefinition(VarDecl * D)306e5dd7070Spatrick void CompleteTentativeDefinition(VarDecl *D) override {
307e5dd7070Spatrick if (Diags.hasErrorOccurred())
308e5dd7070Spatrick return;
309e5dd7070Spatrick
310e5dd7070Spatrick Builder->EmitTentativeDefinition(D);
311e5dd7070Spatrick }
312e5dd7070Spatrick
CompleteExternalDeclaration(VarDecl * D)313e5dd7070Spatrick void CompleteExternalDeclaration(VarDecl *D) override {
314e5dd7070Spatrick Builder->EmitExternalDeclaration(D);
315e5dd7070Spatrick }
316e5dd7070Spatrick
HandleVTable(CXXRecordDecl * RD)317e5dd7070Spatrick void HandleVTable(CXXRecordDecl *RD) override {
318e5dd7070Spatrick if (Diags.hasErrorOccurred())
319e5dd7070Spatrick return;
320e5dd7070Spatrick
321e5dd7070Spatrick Builder->EmitVTable(RD);
322e5dd7070Spatrick }
323e5dd7070Spatrick };
324e5dd7070Spatrick }
325e5dd7070Spatrick
anchor()326e5dd7070Spatrick void CodeGenerator::anchor() { }
327e5dd7070Spatrick
CGM()328e5dd7070Spatrick CodeGenModule &CodeGenerator::CGM() {
329e5dd7070Spatrick return static_cast<CodeGeneratorImpl*>(this)->CGM();
330e5dd7070Spatrick }
331e5dd7070Spatrick
GetModule()332e5dd7070Spatrick llvm::Module *CodeGenerator::GetModule() {
333e5dd7070Spatrick return static_cast<CodeGeneratorImpl*>(this)->GetModule();
334e5dd7070Spatrick }
335e5dd7070Spatrick
ReleaseModule()336e5dd7070Spatrick llvm::Module *CodeGenerator::ReleaseModule() {
337e5dd7070Spatrick return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
338e5dd7070Spatrick }
339e5dd7070Spatrick
getCGDebugInfo()340e5dd7070Spatrick CGDebugInfo *CodeGenerator::getCGDebugInfo() {
341e5dd7070Spatrick return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo();
342e5dd7070Spatrick }
343e5dd7070Spatrick
GetDeclForMangledName(llvm::StringRef name)344e5dd7070Spatrick const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) {
345e5dd7070Spatrick return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
346e5dd7070Spatrick }
347e5dd7070Spatrick
GetMangledName(GlobalDecl GD)348*12c85518Srobert llvm::StringRef CodeGenerator::GetMangledName(GlobalDecl GD) {
349*12c85518Srobert return static_cast<CodeGeneratorImpl *>(this)->GetMangledName(GD);
350*12c85518Srobert }
351*12c85518Srobert
GetAddrOfGlobal(GlobalDecl global,bool isForDefinition)352e5dd7070Spatrick llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global,
353e5dd7070Spatrick bool isForDefinition) {
354e5dd7070Spatrick return static_cast<CodeGeneratorImpl*>(this)
355e5dd7070Spatrick ->GetAddrOfGlobal(global, isForDefinition);
356e5dd7070Spatrick }
357e5dd7070Spatrick
StartModule(llvm::StringRef ModuleName,llvm::LLVMContext & C)358e5dd7070Spatrick llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName,
359e5dd7070Spatrick llvm::LLVMContext &C) {
360e5dd7070Spatrick return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);
361e5dd7070Spatrick }
362e5dd7070Spatrick
363*12c85518Srobert CodeGenerator *
CreateLLVMCodeGen(DiagnosticsEngine & Diags,llvm::StringRef ModuleName,IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,const HeaderSearchOptions & HeaderSearchOpts,const PreprocessorOptions & PreprocessorOpts,const CodeGenOptions & CGO,llvm::LLVMContext & C,CoverageSourceInfo * CoverageInfo)364*12c85518Srobert clang::CreateLLVMCodeGen(DiagnosticsEngine &Diags, llvm::StringRef ModuleName,
365*12c85518Srobert IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
366e5dd7070Spatrick const HeaderSearchOptions &HeaderSearchOpts,
367*12c85518Srobert const PreprocessorOptions &PreprocessorOpts,
368*12c85518Srobert const CodeGenOptions &CGO, llvm::LLVMContext &C,
369*12c85518Srobert CoverageSourceInfo *CoverageInfo) {
370*12c85518Srobert return new CodeGeneratorImpl(Diags, ModuleName, std::move(FS),
371*12c85518Srobert HeaderSearchOpts, PreprocessorOpts, CGO, C,
372*12c85518Srobert CoverageInfo);
373e5dd7070Spatrick }
374