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"
30using namespace CodeGen;
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();
64 std::unique_ptr<llvm::Module> M;
65 std::unique_ptr<CodeGen::CodeGenModule> Builder;
70 static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
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() ||
101 llvm::Module *GetModule() {
106 return Builder->getModuleDebugInfo();
109 llvm::Module *ReleaseModule() {
113 const Decl *GetDeclForMangledName(StringRef MangledName) {
115 if (!Builder->lookupRepresentativeDecl(MangledName, Result))
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 std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
146 OldBuilder->moveLazyEmissionStates(Builder.get());
151 void Initialize(
ASTContext &Context)
override {
157 if (!SDKVersion.empty())
158 M->setSDKVersion(SDKVersion);
160 M->setDarwinTargetVariantTriple(TVT->getTriple());
161 if (
auto TVSDKVersion =
163 M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
165 PreprocessorOpts, CodeGenOpts,
166 *M, Diags, CoverageInfo));
169 Builder->AddDependentLib(Lib);
171 Builder->AppendLinkerOptions(Opt);
174 void HandleCXXStaticMemberVarInstantiation(
VarDecl *VD)
override {
178 Builder->HandleCXXStaticMemberVarInstantiation(VD);
186 HandlingTopLevelDeclRAII HandlingDecl(*
this);
190 Builder->EmitTopLevelDecl(*I);
195 void EmitDeferredDecls() {
196 if (DeferredInlineMemberFuncDefs.empty())
202 HandlingTopLevelDeclRAII HandlingDecl(*
this);
203 for (
unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
204 Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
205 DeferredInlineMemberFuncDefs.clear();
208 void HandleInlineFunctionDefinition(
FunctionDecl *
D)
override {
212 assert(
D->doesThisDeclarationHaveABody());
222 DeferredInlineMemberFuncDefs.push_back(
D);
228 Builder->AddDeferredUnusedCoverageMapping(
D);
235 void HandleTagDeclDefinition(
TagDecl *
D)
override {
241 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
243 Builder->UpdateCompletedType(
D);
252 Builder->EmitGlobal(VD);
260 if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(
Member)) {
262 Builder->EmitGlobal(DRD);
263 }
else if (
auto *DMD = dyn_cast<OMPDeclareMapperDecl>(
Member)) {
265 Builder->EmitGlobal(DMD);
271 void HandleTagDeclRequiredDefinition(
const TagDecl *
D)
override {
277 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
280 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(
D))
281 DI->completeRequiredType(RD);
284 void HandleTranslationUnit(
ASTContext &Ctx)
override {
303 Builder->RefreshTypeCacheForClass(RD);
306 void CompleteTentativeDefinition(
VarDecl *
D)
override {
310 Builder->EmitTentativeDefinition(
D);
314 Builder->EmitExternalDeclaration(
D);
321 Builder->EmitVTable(RD);
326void CodeGenerator::anchor() { }
329 return static_cast<CodeGeneratorImpl*
>(
this)->
CGM();
333 return static_cast<CodeGeneratorImpl*
>(
this)->
GetModule();
337 return static_cast<CodeGeneratorImpl*
>(
this)->
ReleaseModule();
349 return static_cast<CodeGeneratorImpl *
>(
this)->
GetMangledName(GD);
353 bool isForDefinition) {
354 return static_cast<CodeGeneratorImpl*
>(
this)
359 llvm::LLVMContext &
C) {
360 return static_cast<CodeGeneratorImpl*
>(
this)->
StartModule(ModuleName,
C);
370 return new CodeGeneratorImpl(Diags, ModuleName, std::move(FS),
371 HeaderSearchOpts, PreprocessorOpts, CGO,
C,
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen'ed or deserialized from PCH lazily, only when used; this is onl...
bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const
Returns true if this is an inline-initialized static data member which is treated as a definition for...
const LangOptions & getLangOpts() const
const TargetInfo & getTargetInfo() const
Represents a C++ struct/union/class.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::vector< std::string > DependentLibraries
A list of dependent libraries.
std::string MainFileName
The user provided name for the "main file", if non-empty.
std::vector< std::string > LinkerOptions
A list of linker options to embed in the object file.
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 - This represents one declaration (or definition), e.g.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Represents a ValueDecl that came out of a declarator.
Concrete class used by the front-end to report problems and issues.
bool hasErrorOccurred() const
bool hasUnrecoverableErrorOccurred() const
Determine whether any kind of unrecoverable error has occurred.
Represents a function declaration or definition.
GlobalDecl - represents a global declaration.
Describes a module or submodule.
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
Represents a struct/union/class.
Represents the declaration of a struct/union/class/enum.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
const char * getDataLayoutString() const
const llvm::Triple * getDarwinTargetVariantTriple() const
Returns the darwin target variant triple, the variant of the deployment target for which the code is ...
const std::optional< VersionTuple > getDarwinTargetVariantSDKVersion() const
Returns the version of the darwin target variant SDK which was used during the compilation if one was...
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
const llvm::VersionTuple & getSDKVersion() const
Represents a variable declaration or definition.
Defines the clang::TargetInfo interface.
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.
Diagnostic wrappers for TextAPI types for error reporting.