23#include "llvm/ADT/StringRef.h"
24#include "llvm/IR/DataLayout.h"
25#include "llvm/IR/LLVMContext.h"
26#include "llvm/IR/Module.h"
27#include "llvm/Support/FormatVariadic.h"
28#include "llvm/Support/VirtualFileSystem.h"
36 DiagnosticsEngine &Diags;
38 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
39 const HeaderSearchOptions &HeaderSearchOpts;
40 const PreprocessorOptions &PreprocessorOpts;
41 const CodeGenOptions &CodeGenOpts;
43 unsigned HandlingTopLevelDecls;
48 struct HandlingTopLevelDeclRAII {
49 CodeGeneratorImpl &Self;
51 HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
52 bool EmitDeferred =
true)
53 : Self(Self), EmitDeferred(EmitDeferred) {
54 ++Self.HandlingTopLevelDecls;
56 ~HandlingTopLevelDeclRAII() {
57 unsigned Level = --Self.HandlingTopLevelDecls;
58 if (Level == 0 && EmitDeferred)
59 Self.EmitDeferredDecls();
63 CoverageSourceInfo *CoverageInfo;
64 std::unique_ptr<llvm::Module> M;
65 std::unique_ptr<CodeGen::CodeGenModule> Builder;
66 SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
68 static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
69 const CodeGenOptions &CGO) {
76 CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
77 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
78 const HeaderSearchOptions &HSO,
79 const PreprocessorOptions &PPO,
const CodeGenOptions &CGO,
81 CoverageSourceInfo *CoverageInfo =
nullptr)
82 : Diags(diags), Ctx(
nullptr), FS(std::move(FS)), HeaderSearchOpts(HSO),
83 PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
84 CoverageInfo(CoverageInfo),
85 M(new llvm::
Module(ExpandModuleName(ModuleName, CGO),
C)) {
86 C.setDiscardValueNames(CGO.DiscardValueNames);
89 ~CodeGeneratorImpl()
override {
91 assert(DeferredInlineMemberFuncDefs.empty() ||
92 Diags.hasErrorOccurred());
95 CodeGenModule &CGM() {
99 llvm::Module *GetModule() {
103 CGDebugInfo *getCGDebugInfo() {
104 return Builder->getModuleDebugInfo();
107 std::unique_ptr<llvm::Module> ReleaseModule() {
108 return std::exchange(M,
nullptr);
111 const Decl *GetDeclForMangledName(StringRef MangledName) {
113 if (!Builder->lookupRepresentativeDecl(MangledName,
Result))
115 const Decl *D =
Result.getCanonicalDecl().getDecl();
116 if (
auto FD = dyn_cast<FunctionDecl>(D)) {
119 }
else if (
auto TD = dyn_cast<TagDecl>(D)) {
120 if (
auto Def = TD->getDefinition())
126 llvm::StringRef GetMangledName(GlobalDecl GD) {
127 return Builder->getMangledName(GD);
130 llvm::Constant *GetAddrOfGlobal(GlobalDecl global,
bool isForDefinition) {
131 return Builder->GetAddrOfGlobal(global,
ForDefinition_t(isForDefinition));
134 llvm::Module *StartModule(llvm::StringRef ModuleName,
135 llvm::LLVMContext &
C) {
136 assert(!M &&
"Replacing existing Module?");
137 M.reset(
new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts),
C));
139 IRGenFinished =
false;
141 std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
143 assert(Ctx &&
"must call Initialize() before calling StartModule()");
147 OldBuilder->moveLazyEmissionStates(Builder.get());
152 void Initialize(ASTContext &Context)
override {
155 M->setTargetTriple(Ctx->getTargetInfo().getTriple());
156 M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
158 if (!SDKVersion.empty())
159 M->setSDKVersion(SDKVersion);
160 if (
const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
161 M->setDarwinTargetVariantTriple(TVT->getTriple());
162 if (
auto TVSDKVersion =
163 Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
164 M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
165 Builder.reset(
new CodeGen::CodeGenModule(Context, FS, HeaderSearchOpts,
166 PreprocessorOpts, CodeGenOpts,
167 *M, Diags, CoverageInfo));
169 for (
auto &&Lib : CodeGenOpts.DependentLibraries)
170 Builder->AddDependentLib(Lib);
171 for (
auto &&Opt : CodeGenOpts.LinkerOptions)
172 Builder->AppendLinkerOptions(Opt);
175 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD)
override {
176 if (Diags.hasErrorOccurred())
179 Builder->HandleCXXStaticMemberVarInstantiation(VD);
182 bool HandleTopLevelDecl(DeclGroupRef DG)
override {
188 if (Diags.hasUnrecoverableErrorOccurred())
191 HandlingTopLevelDeclRAII HandlingDecl(*
this);
195 Builder->EmitTopLevelDecl(I);
200 void EmitDeferredDecls() {
201 if (DeferredInlineMemberFuncDefs.empty())
207 HandlingTopLevelDeclRAII HandlingDecl(*
this);
208 for (
unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
209 Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
210 DeferredInlineMemberFuncDefs.clear();
213 void HandleInlineFunctionDefinition(FunctionDecl *D)
override {
214 if (Diags.hasUnrecoverableErrorOccurred())
227 DeferredInlineMemberFuncDefs.push_back(D);
233 Builder->AddDeferredUnusedCoverageMapping(D);
240 void HandleTagDeclDefinition(TagDecl *D)
override {
241 if (Diags.hasUnrecoverableErrorOccurred())
246 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
248 Builder->UpdateCompletedType(D);
252 assert(Ctx &&
"Initialize() not called");
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);
370std::unique_ptr<CodeGenerator>
377 return std::make_unique<CodeGeneratorImpl>(Diags, ModuleName, std::move(FS),
378 HeaderSearchOpts, PreprocessorOpts,
379 CGO,
C, CoverageInfo);
382std::unique_ptr<CodeGenerator>
384 llvm::LLVMContext &
C,
394std::optional<std::pair<StringRef, StringRef>>
396 static auto TrapRegex =
397 llvm::Regex(llvm::formatv(
"^{0}\\$(.*)\\$(.*)$",
ClangTrapPrefix).str());
399 std::string *ErrorPtr =
nullptr;
404 if (!TrapRegex.match(FuncName, &Matches, ErrorPtr)) {
405 assert(ErrorPtr && ErrorPtr->empty() &&
"Invalid regex pattern");
409 if (Matches.size() != 3) {
410 assert(0 &&
"Expected 3 matches from Regex::match");
415 return std::make_pair(Matches[1], Matches[2]);
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
constexpr llvm::StringRef ClangTrapPrefix
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.
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.
std::unique_ptr< llvm::Module > ReleaseModule()
Release ownership of the module to the caller.
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.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
HeaderSearchOptions & getHeaderSearchOpts()
PreprocessorOptions & getPreprocessorOpts()
CodeGenOptions & getCodeGenOpts()
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 ...
std::optional< std::pair< StringRef, StringRef > > DemangleTrapReasonInDebugInfo(StringRef FuncName)
Demangle the artificial function name (.
The JSON file list parser is used to communicate input to InstallAPI.
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.
std::unique_ptr< CodeGenerator > CreateLLVMCodeGen(const CompilerInstance &CI, llvm::StringRef ModuleName, llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo=nullptr)
CreateLLVMCodeGen - Create a CodeGenerator instance.