24#include "llvm/ADT/StringRef.h"
25#include "llvm/IR/DataLayout.h"
26#include "llvm/IR/LLVMContext.h"
27#include "llvm/IR/Module.h"
28#include "llvm/Support/FormatVariadic.h"
29#include "llvm/Support/VirtualFileSystem.h"
37 DiagnosticsEngine &Diags;
39 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
40 const HeaderSearchOptions &HeaderSearchOpts;
41 const PreprocessorOptions &PreprocessorOpts;
42 const CodeGenOptions &CodeGenOpts;
44 unsigned HandlingTopLevelDecls;
49 struct HandlingTopLevelDeclRAII {
50 CodeGeneratorImpl &Self;
52 HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
53 bool EmitDeferred =
true)
54 : Self(Self), EmitDeferred(EmitDeferred) {
55 ++Self.HandlingTopLevelDecls;
57 ~HandlingTopLevelDeclRAII() {
58 unsigned Level = --Self.HandlingTopLevelDecls;
59 if (
Level == 0 && EmitDeferred)
60 Self.EmitDeferredDecls();
64 CoverageSourceInfo *CoverageInfo;
65 std::unique_ptr<llvm::Module> M;
66 std::unique_ptr<CodeGen::CodeGenModule> Builder;
67 SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
69 static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
70 const CodeGenOptions &CGO) {
77 CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
78 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
79 const HeaderSearchOptions &HSO,
80 const PreprocessorOptions &PPO,
const CodeGenOptions &CGO,
82 CoverageSourceInfo *CoverageInfo =
nullptr)
83 : Diags(diags), Ctx(
nullptr), FS(std::move(FS)), HeaderSearchOpts(HSO),
84 PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
85 CoverageInfo(CoverageInfo),
86 M(new llvm::
Module(ExpandModuleName(ModuleName, CGO),
C)) {
87 C.setDiscardValueNames(CGO.DiscardValueNames);
90 ~CodeGeneratorImpl()
override {
92 assert(DeferredInlineMemberFuncDefs.empty() ||
93 Diags.hasErrorOccurred());
96 CodeGenModule &CGM() {
100 llvm::Module *GetModule() {
104 CGDebugInfo *getCGDebugInfo() {
105 return Builder->getModuleDebugInfo();
108 std::unique_ptr<llvm::Module> ReleaseModule() {
109 return std::exchange(M,
nullptr);
112 const Decl *GetDeclForMangledName(StringRef MangledName) {
114 if (!Builder->lookupRepresentativeDecl(MangledName,
Result))
116 const Decl *D =
Result.getCanonicalDecl().getDecl();
117 if (
auto FD = dyn_cast<FunctionDecl>(D)) {
120 }
else if (
auto TD = dyn_cast<TagDecl>(D)) {
121 if (
auto Def = TD->getDefinition())
127 llvm::StringRef GetMangledName(GlobalDecl GD) {
128 return Builder->getMangledName(GD);
131 llvm::Constant *GetAddrOfGlobal(GlobalDecl global,
bool isForDefinition) {
132 return Builder->GetAddrOfGlobal(global,
ForDefinition_t(isForDefinition));
135 llvm::Constant *GetAddrOfVTable(BaseSubobject subobject,
136 const CXXRecordDecl *
decl) {
137 return Builder->getCXXABI().getVTableAddressPoint(subobject,
decl);
140 llvm::Module *StartModule(llvm::StringRef ModuleName,
141 llvm::LLVMContext &
C) {
142 assert(!M &&
"Replacing existing Module?");
143 M.reset(
new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts),
C));
145 IRGenFinished =
false;
147 std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
149 assert(Ctx &&
"must call Initialize() before calling StartModule()");
153 OldBuilder->moveLazyEmissionStates(Builder.get());
158 void Initialize(ASTContext &Context)
override {
161 M->setTargetTriple(Ctx->getTargetInfo().getTriple());
162 M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
164 if (!SDKVersion.empty())
165 M->setSDKVersion(SDKVersion);
166 if (
const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
167 M->setDarwinTargetVariantTriple(TVT->getTriple());
168 if (
auto TVSDKVersion =
169 Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
170 M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
171 Builder.reset(
new CodeGen::CodeGenModule(Context, FS, HeaderSearchOpts,
172 PreprocessorOpts, CodeGenOpts,
173 *M, Diags, CoverageInfo));
175 for (
auto &&Lib : CodeGenOpts.DependentLibraries)
176 Builder->AddDependentLib(Lib);
177 for (
auto &&Opt : CodeGenOpts.LinkerOptions)
178 Builder->AppendLinkerOptions(Opt);
181 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD)
override {
182 if (Diags.hasErrorOccurred())
185 Builder->HandleCXXStaticMemberVarInstantiation(VD);
188 bool HandleTopLevelDecl(DeclGroupRef DG)
override {
194 if (Diags.hasUnrecoverableErrorOccurred())
197 HandlingTopLevelDeclRAII HandlingDecl(*
this);
201 Builder->EmitTopLevelDecl(I);
206 void EmitDeferredDecls() {
207 if (DeferredInlineMemberFuncDefs.empty())
213 HandlingTopLevelDeclRAII HandlingDecl(*
this);
214 for (
unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
215 Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
216 DeferredInlineMemberFuncDefs.clear();
219 void HandleInlineFunctionDefinition(FunctionDecl *D)
override {
220 if (Diags.hasUnrecoverableErrorOccurred())
233 DeferredInlineMemberFuncDefs.push_back(D);
240 Builder->AddDeferredUnusedCoverageMapping(D);
247 void HandleTagDeclDefinition(TagDecl *D)
override {
248 if (Diags.hasUnrecoverableErrorOccurred())
253 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
255 Builder->UpdateCompletedType(D);
259 assert(Ctx &&
"Initialize() not called");
260 if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
262 if (VarDecl *VD = dyn_cast<VarDecl>(
Member)) {
263 if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
264 Ctx->DeclMustBeEmitted(VD)) {
265 Builder->EmitGlobal(VD);
274 if (
auto *RD = dyn_cast<CXXRecordDecl>(D);
275 RD && RD->hasAttr<DLLExportAttr>()) {
277 if (
auto *CD = dyn_cast<CXXConstructorDecl>(
Member)) {
278 if (CD->getInheritedConstructor() && CD->hasAttr<DLLExportAttr>() &&
280 Builder->EmitTopLevelDecl(CD);
286 if (Ctx->getLangOpts().OpenMP) {
288 if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(
Member)) {
289 if (Ctx->DeclMustBeEmitted(DRD))
290 Builder->EmitGlobal(DRD);
291 }
else if (
auto *DMD = dyn_cast<OMPDeclareMapperDecl>(
Member)) {
292 if (Ctx->DeclMustBeEmitted(DMD))
293 Builder->EmitGlobal(DMD);
299 void HandleTagDeclRequiredDefinition(
const TagDecl *D)
override {
300 if (Diags.hasUnrecoverableErrorOccurred())
305 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
307 if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
308 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(D))
309 DI->completeRequiredType(RD);
312 void HandleTranslationUnit(ASTContext &Ctx)
override {
314 if (!Diags.hasUnrecoverableErrorOccurred() && Builder)
319 if (Diags.hasErrorOccurred()) {
325 IRGenFinished =
true;
328 void AssignInheritanceModel(CXXRecordDecl *RD)
override {
329 if (Diags.hasUnrecoverableErrorOccurred())
332 Builder->RefreshTypeCacheForClass(RD);
335 void CompleteTentativeDefinition(VarDecl *D)
override {
336 if (Diags.hasUnrecoverableErrorOccurred())
339 Builder->EmitTentativeDefinition(D);
342 void CompleteExternalDeclaration(DeclaratorDecl *D)
override {
343 Builder->EmitExternalDeclaration(D);
346 void HandleVTable(CXXRecordDecl *RD)
override {
347 if (Diags.hasUnrecoverableErrorOccurred())
350 Builder->EmitVTable(RD);
355void CodeGenerator::anchor() { }
358 return static_cast<CodeGeneratorImpl*
>(
this)->
CGM();
362 return static_cast<CodeGeneratorImpl*
>(
this)->
GetModule();
366 return static_cast<CodeGeneratorImpl*
>(
this)->
ReleaseModule();
378 return static_cast<CodeGeneratorImpl *
>(
this)->
GetMangledName(GD);
382 bool isForDefinition) {
383 return static_cast<CodeGeneratorImpl*
>(
this)
393 llvm::LLVMContext &
C) {
394 return static_cast<CodeGeneratorImpl*
>(
this)->
StartModule(ModuleName,
C);
397std::unique_ptr<CodeGenerator>
404 return std::make_unique<CodeGeneratorImpl>(Diags, ModuleName, std::move(FS),
405 HeaderSearchOpts, PreprocessorOpts,
406 CGO,
C, CoverageInfo);
409std::unique_ptr<CodeGenerator>
411 llvm::LLVMContext &
C,
421std::optional<std::pair<StringRef, StringRef>>
423 static const auto TrapRegex =
424 llvm::Regex(llvm::formatv(
"^{0}\\$(.*)\\$(.*)$",
ClangTrapPrefix).str());
426 std::string *ErrorPtr =
nullptr;
431 if (!TrapRegex.match(FuncName, &Matches, ErrorPtr)) {
432 assert(ErrorPtr && ErrorPtr->empty() &&
"Invalid regex pattern");
436 if (Matches.size() != 3) {
437 assert(0 &&
"Expected 3 matches from Regex::match");
442 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
Represents a C++ struct/union/class.
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...
llvm::Constant * GetAddrOfVTable(BaseSubobject base, const CXXRecordDecl *decl)
Return the LLVM address of the vtable for the given base subobject.
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.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
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 isImmediateFunction() const
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 (.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
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.