22#include "llvm/ADT/StringRef.h"
23#include "llvm/IR/DataLayout.h"
24#include "llvm/IR/LLVMContext.h"
25#include "llvm/IR/Module.h"
26#include "llvm/Support/VirtualFileSystem.h"
34 DiagnosticsEngine &Diags;
36 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
37 const HeaderSearchOptions &HeaderSearchOpts;
38 const PreprocessorOptions &PreprocessorOpts;
39 const CodeGenOptions &CodeGenOpts;
41 unsigned HandlingTopLevelDecls;
46 struct HandlingTopLevelDeclRAII {
47 CodeGeneratorImpl &Self;
49 HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
50 bool EmitDeferred =
true)
51 : Self(Self), EmitDeferred(EmitDeferred) {
52 ++Self.HandlingTopLevelDecls;
54 ~HandlingTopLevelDeclRAII() {
55 unsigned Level = --Self.HandlingTopLevelDecls;
56 if (Level == 0 && EmitDeferred)
57 Self.EmitDeferredDecls();
61 CoverageSourceInfo *CoverageInfo;
64 std::unique_ptr<llvm::Module> M;
65 std::unique_ptr<CodeGen::CodeGenModule> Builder;
68 SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
70 static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
71 const CodeGenOptions &CGO) {
78 CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
79 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
80 const HeaderSearchOptions &HSO,
81 const PreprocessorOptions &PPO,
const CodeGenOptions &CGO,
83 CoverageSourceInfo *CoverageInfo =
nullptr)
84 : Diags(diags), Ctx(
nullptr), FS(std::move(FS)), HeaderSearchOpts(HSO),
85 PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
86 CoverageInfo(CoverageInfo),
87 M(new llvm::
Module(ExpandModuleName(ModuleName, CGO),
C)) {
88 C.setDiscardValueNames(CGO.DiscardValueNames);
91 ~CodeGeneratorImpl()
override {
93 assert(DeferredInlineMemberFuncDefs.empty() ||
94 Diags.hasErrorOccurred());
97 CodeGenModule &CGM() {
101 llvm::Module *GetModule() {
105 CGDebugInfo *getCGDebugInfo() {
106 return Builder->getModuleDebugInfo();
109 llvm::Module *ReleaseModule() {
113 const Decl *GetDeclForMangledName(StringRef MangledName) {
115 if (!Builder->lookupRepresentativeDecl(MangledName,
Result))
117 const Decl *D =
Result.getCanonicalDecl().getDecl();
118 if (
auto FD = dyn_cast<FunctionDecl>(D)) {
121 }
else if (
auto TD = dyn_cast<TagDecl>(D)) {
122 if (
auto Def = TD->getDefinition())
128 llvm::StringRef GetMangledName(GlobalDecl GD) {
129 return Builder->getMangledName(GD);
132 llvm::Constant *GetAddrOfGlobal(GlobalDecl global,
bool isForDefinition) {
133 return Builder->GetAddrOfGlobal(global,
ForDefinition_t(isForDefinition));
136 llvm::Module *StartModule(llvm::StringRef ModuleName,
137 llvm::LLVMContext &
C) {
138 assert(!M &&
"Replacing existing Module?");
139 M.reset(
new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts),
C));
141 IRGenFinished =
false;
143 std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
148 OldBuilder->moveLazyEmissionStates(Builder.get());
153 void Initialize(ASTContext &Context)
override {
156 M->setTargetTriple(Ctx->getTargetInfo().getTriple());
157 M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
159 if (!SDKVersion.empty())
160 M->setSDKVersion(SDKVersion);
161 if (
const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
162 M->setDarwinTargetVariantTriple(TVT->getTriple());
163 if (
auto TVSDKVersion =
164 Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
165 M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
166 Builder.reset(
new CodeGen::CodeGenModule(Context, FS, HeaderSearchOpts,
167 PreprocessorOpts, CodeGenOpts,
168 *M, Diags, CoverageInfo));
170 for (
auto &&Lib : CodeGenOpts.DependentLibraries)
171 Builder->AddDependentLib(Lib);
172 for (
auto &&Opt : CodeGenOpts.LinkerOptions)
173 Builder->AppendLinkerOptions(Opt);
176 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD)
override {
177 if (Diags.hasErrorOccurred())
180 Builder->HandleCXXStaticMemberVarInstantiation(VD);
183 bool HandleTopLevelDecl(DeclGroupRef DG)
override {
189 if (Diags.hasUnrecoverableErrorOccurred())
192 HandlingTopLevelDeclRAII HandlingDecl(*
this);
196 Builder->EmitTopLevelDecl(I);
201 void EmitDeferredDecls() {
202 if (DeferredInlineMemberFuncDefs.empty())
208 HandlingTopLevelDeclRAII HandlingDecl(*
this);
209 for (
unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
210 Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
211 DeferredInlineMemberFuncDefs.clear();
214 void HandleInlineFunctionDefinition(FunctionDecl *D)
override {
215 if (Diags.hasUnrecoverableErrorOccurred())
228 DeferredInlineMemberFuncDefs.push_back(D);
234 Builder->AddDeferredUnusedCoverageMapping(D);
241 void HandleTagDeclDefinition(TagDecl *D)
override {
242 if (Diags.hasUnrecoverableErrorOccurred())
247 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
249 Builder->UpdateCompletedType(D);
253 if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
255 if (VarDecl *VD = dyn_cast<VarDecl>(
Member)) {
256 if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
257 Ctx->DeclMustBeEmitted(VD)) {
258 Builder->EmitGlobal(VD);
264 if (Ctx->getLangOpts().OpenMP) {
266 if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(
Member)) {
267 if (Ctx->DeclMustBeEmitted(DRD))
268 Builder->EmitGlobal(DRD);
269 }
else if (
auto *DMD = dyn_cast<OMPDeclareMapperDecl>(
Member)) {
270 if (Ctx->DeclMustBeEmitted(DMD))
271 Builder->EmitGlobal(DMD);
277 void HandleTagDeclRequiredDefinition(
const TagDecl *D)
override {
278 if (Diags.hasUnrecoverableErrorOccurred())
283 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
285 if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
286 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(D))
287 DI->completeRequiredType(RD);
290 void HandleTranslationUnit(ASTContext &Ctx)
override {
292 if (!Diags.hasUnrecoverableErrorOccurred() && Builder)
297 if (Diags.hasErrorOccurred()) {
303 IRGenFinished =
true;
306 void AssignInheritanceModel(CXXRecordDecl *RD)
override {
307 if (Diags.hasUnrecoverableErrorOccurred())
310 Builder->RefreshTypeCacheForClass(RD);
313 void CompleteTentativeDefinition(VarDecl *D)
override {
314 if (Diags.hasUnrecoverableErrorOccurred())
317 Builder->EmitTentativeDefinition(D);
320 void CompleteExternalDeclaration(DeclaratorDecl *D)
override {
321 Builder->EmitExternalDeclaration(D);
324 void HandleVTable(CXXRecordDecl *RD)
override {
325 if (Diags.hasUnrecoverableErrorOccurred())
328 Builder->EmitVTable(RD);
333void CodeGenerator::anchor() { }
336 return static_cast<CodeGeneratorImpl*
>(
this)->
CGM();
340 return static_cast<CodeGeneratorImpl*
>(
this)->
GetModule();
344 return static_cast<CodeGeneratorImpl*
>(
this)->
ReleaseModule();
356 return static_cast<CodeGeneratorImpl *
>(
this)->
GetMangledName(GD);
360 bool isForDefinition) {
361 return static_cast<CodeGeneratorImpl*
>(
this)
366 llvm::LLVMContext &
C) {
367 return static_cast<CodeGeneratorImpl*
>(
this)->
StartModule(ModuleName,
C);
377 return new CodeGeneratorImpl(Diags, ModuleName, std::move(FS),
378 HeaderSearchOpts, PreprocessorOpts, CGO,
C,
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
const TargetInfo & getTargetInfo() const
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string MainFileName
The user provided name for the "main file", if non-empty.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
This class organizes the cross-function state that is used while generating LLVM code.
The primary public interface to the Clang code generator.
llvm::Module * ReleaseModule()
Release ownership of the module to the caller.
const Decl * GetDeclForMangledName(llvm::StringRef MangledName)
Given a mangled name, return a declaration which mangles that way which has been added to this code g...
llvm::Module * StartModule(llvm::StringRef ModuleName, llvm::LLVMContext &C)
Create a new llvm::Module after calling HandleTranslationUnit.
llvm::Constant * GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition)
Return the LLVM address of the given global entity.
llvm::StringRef GetMangledName(GlobalDecl GD)
Given a global declaration, return a mangled name for this declaration which has been added to this c...
CodeGen::CGDebugInfo * getCGDebugInfo()
Return debug info code generator.
CodeGen::CodeGenModule & CGM()
Return an opaque reference to the CodeGenModule object, which can be used in various secondary APIs.
llvm::Module * GetModule()
Return the module that this code generator is building into.
Stores additional source code information like skipped ranges which is required by the coverage mappi...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Decl - This represents one declaration (or definition), e.g.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Concrete class used by the front-end to report problems and issues.
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
GlobalDecl - represents a global declaration.
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
const llvm::VersionTuple & getSDKVersion() const
Defines the clang::TargetInfo interface.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
The JSON file list parser is used to communicate input to InstallAPI.
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=nullptr)
CreateLLVMCodeGen - Create a CodeGenerator instance.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
@ Result
The result type of a method or function.