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/FormatVariadic.h"
27#include "llvm/Support/VirtualFileSystem.h"
35 DiagnosticsEngine &Diags;
37 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
38 const HeaderSearchOptions &HeaderSearchOpts;
39 const PreprocessorOptions &PreprocessorOpts;
40 const CodeGenOptions &CodeGenOpts;
42 unsigned HandlingTopLevelDecls;
47 struct HandlingTopLevelDeclRAII {
48 CodeGeneratorImpl &Self;
50 HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
51 bool EmitDeferred =
true)
52 : Self(Self), EmitDeferred(EmitDeferred) {
53 ++Self.HandlingTopLevelDecls;
55 ~HandlingTopLevelDeclRAII() {
56 unsigned Level = --Self.HandlingTopLevelDecls;
57 if (Level == 0 && EmitDeferred)
58 Self.EmitDeferredDecls();
62 CoverageSourceInfo *CoverageInfo;
65 std::unique_ptr<llvm::Module> M;
66 std::unique_ptr<CodeGen::CodeGenModule> Builder;
69 SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
71 static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
72 const CodeGenOptions &CGO) {
79 CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
80 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
81 const HeaderSearchOptions &HSO,
82 const PreprocessorOptions &PPO,
const CodeGenOptions &CGO,
84 CoverageSourceInfo *CoverageInfo =
nullptr)
85 : Diags(diags), Ctx(
nullptr), FS(std::move(FS)), HeaderSearchOpts(HSO),
86 PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
87 CoverageInfo(CoverageInfo),
88 M(new llvm::
Module(ExpandModuleName(ModuleName, CGO),
C)) {
89 C.setDiscardValueNames(CGO.DiscardValueNames);
92 ~CodeGeneratorImpl()
override {
94 assert(DeferredInlineMemberFuncDefs.empty() ||
95 Diags.hasErrorOccurred());
98 CodeGenModule &CGM() {
102 llvm::Module *GetModule() {
106 CGDebugInfo *getCGDebugInfo() {
107 return Builder->getModuleDebugInfo();
110 llvm::Module *ReleaseModule() {
114 const Decl *GetDeclForMangledName(StringRef MangledName) {
116 if (!Builder->lookupRepresentativeDecl(MangledName,
Result))
118 const Decl *D =
Result.getCanonicalDecl().getDecl();
119 if (
auto FD = dyn_cast<FunctionDecl>(D)) {
122 }
else if (
auto TD = dyn_cast<TagDecl>(D)) {
123 if (
auto Def = TD->getDefinition())
129 llvm::StringRef GetMangledName(GlobalDecl GD) {
130 return Builder->getMangledName(GD);
133 llvm::Constant *GetAddrOfGlobal(GlobalDecl global,
bool isForDefinition) {
134 return Builder->GetAddrOfGlobal(global,
ForDefinition_t(isForDefinition));
137 llvm::Module *StartModule(llvm::StringRef ModuleName,
138 llvm::LLVMContext &
C) {
139 assert(!M &&
"Replacing existing Module?");
140 M.reset(
new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts),
C));
142 IRGenFinished =
false;
144 std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
149 OldBuilder->moveLazyEmissionStates(Builder.get());
154 void Initialize(ASTContext &Context)
override {
157 M->setTargetTriple(Ctx->getTargetInfo().getTriple());
158 M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
160 if (!SDKVersion.empty())
161 M->setSDKVersion(SDKVersion);
162 if (
const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
163 M->setDarwinTargetVariantTriple(TVT->getTriple());
164 if (
auto TVSDKVersion =
165 Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
166 M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
167 Builder.reset(
new CodeGen::CodeGenModule(Context, FS, HeaderSearchOpts,
168 PreprocessorOpts, CodeGenOpts,
169 *M, Diags, CoverageInfo));
171 for (
auto &&Lib : CodeGenOpts.DependentLibraries)
172 Builder->AddDependentLib(Lib);
173 for (
auto &&Opt : CodeGenOpts.LinkerOptions)
174 Builder->AppendLinkerOptions(Opt);
177 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD)
override {
178 if (Diags.hasErrorOccurred())
181 Builder->HandleCXXStaticMemberVarInstantiation(VD);
184 bool HandleTopLevelDecl(DeclGroupRef DG)
override {
190 if (Diags.hasUnrecoverableErrorOccurred())
193 HandlingTopLevelDeclRAII HandlingDecl(*
this);
197 Builder->EmitTopLevelDecl(I);
202 void EmitDeferredDecls() {
203 if (DeferredInlineMemberFuncDefs.empty())
209 HandlingTopLevelDeclRAII HandlingDecl(*
this);
210 for (
unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
211 Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
212 DeferredInlineMemberFuncDefs.clear();
215 void HandleInlineFunctionDefinition(FunctionDecl *D)
override {
216 if (Diags.hasUnrecoverableErrorOccurred())
229 DeferredInlineMemberFuncDefs.push_back(D);
235 Builder->AddDeferredUnusedCoverageMapping(D);
242 void HandleTagDeclDefinition(TagDecl *D)
override {
243 if (Diags.hasUnrecoverableErrorOccurred())
248 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
250 Builder->UpdateCompletedType(D);
254 if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
256 if (VarDecl *VD = dyn_cast<VarDecl>(
Member)) {
257 if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
258 Ctx->DeclMustBeEmitted(VD)) {
259 Builder->EmitGlobal(VD);
265 if (Ctx->getLangOpts().OpenMP) {
267 if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(
Member)) {
268 if (Ctx->DeclMustBeEmitted(DRD))
269 Builder->EmitGlobal(DRD);
270 }
else if (
auto *DMD = dyn_cast<OMPDeclareMapperDecl>(
Member)) {
271 if (Ctx->DeclMustBeEmitted(DMD))
272 Builder->EmitGlobal(DMD);
278 void HandleTagDeclRequiredDefinition(
const TagDecl *D)
override {
279 if (Diags.hasUnrecoverableErrorOccurred())
284 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
286 if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
287 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(D))
288 DI->completeRequiredType(RD);
291 void HandleTranslationUnit(ASTContext &Ctx)
override {
293 if (!Diags.hasUnrecoverableErrorOccurred() && Builder)
298 if (Diags.hasErrorOccurred()) {
304 IRGenFinished =
true;
307 void AssignInheritanceModel(CXXRecordDecl *RD)
override {
308 if (Diags.hasUnrecoverableErrorOccurred())
311 Builder->RefreshTypeCacheForClass(RD);
314 void CompleteTentativeDefinition(VarDecl *D)
override {
315 if (Diags.hasUnrecoverableErrorOccurred())
318 Builder->EmitTentativeDefinition(D);
321 void CompleteExternalDeclaration(DeclaratorDecl *D)
override {
322 Builder->EmitExternalDeclaration(D);
325 void HandleVTable(CXXRecordDecl *RD)
override {
326 if (Diags.hasUnrecoverableErrorOccurred())
329 Builder->EmitVTable(RD);
334void CodeGenerator::anchor() { }
337 return static_cast<CodeGeneratorImpl*
>(
this)->
CGM();
341 return static_cast<CodeGeneratorImpl*
>(
this)->
GetModule();
345 return static_cast<CodeGeneratorImpl*
>(
this)->
ReleaseModule();
357 return static_cast<CodeGeneratorImpl *
>(
this)->
GetMangledName(GD);
361 bool isForDefinition) {
362 return static_cast<CodeGeneratorImpl*
>(
this)
367 llvm::LLVMContext &
C) {
368 return static_cast<CodeGeneratorImpl*
>(
this)->
StartModule(ModuleName,
C);
378 return new CodeGeneratorImpl(Diags, ModuleName, std::move(FS),
379 HeaderSearchOpts, PreprocessorOpts, CGO,
C,
385std::optional<std::pair<StringRef, StringRef>>
387 static auto TrapRegex =
388 llvm::Regex(llvm::formatv(
"^{0}\\$(.*)\\$(.*)$",
ClangTrapPrefix).str());
390 std::string *ErrorPtr =
nullptr;
395 if (!TrapRegex.match(FuncName, &Matches, ErrorPtr)) {
396 assert(ErrorPtr && ErrorPtr->empty() &&
"Invalid regex pattern");
400 if (Matches.size() != 3) {
401 assert(0 &&
"Expected 3 matches from Regex::match");
406 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.
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 ...
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.
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.