23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/IR/DataLayout.h"
25 #include "llvm/IR/LLVMContext.h"
26 #include "llvm/IR/Module.h"
29 using namespace clang;
30 using namespace CodeGen;
40 unsigned HandlingTopLevelDecls;
45 struct HandlingTopLevelDeclRAII {
46 CodeGeneratorImpl &Self;
48 HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
49 bool EmitDeferred =
true)
50 : Self(Self), EmitDeferred(EmitDeferred) {
51 ++Self.HandlingTopLevelDecls;
53 ~HandlingTopLevelDeclRAII() {
54 unsigned Level = --Self.HandlingTopLevelDecls;
55 if (Level == 0 && EmitDeferred)
56 Self.EmitDeferredDecls();
63 std::unique_ptr<llvm::Module> M;
64 std::unique_ptr<CodeGen::CodeGenModule>
Builder;
75 : Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO),
76 PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
77 CoverageInfo(CoverageInfo), M(new llvm::
Module(ModuleName, C)) {
78 C.setDiscardValueNames(CGO.DiscardValueNames);
81 ~CodeGeneratorImpl()
override {
83 assert(DeferredInlineMethodDefinitions.empty() ||
84 Diags.hasErrorOccurred());
91 llvm::Module *GetModule() {
95 llvm::Module *ReleaseModule() {
99 const Decl *GetDeclForMangledName(StringRef MangledName) {
101 if (!
Builder->lookupRepresentativeDecl(MangledName, Result))
104 if (
auto FD = dyn_cast<FunctionDecl>(D)) {
107 }
else if (
auto TD = dyn_cast<TagDecl>(D)) {
108 if (
auto Def = TD->getDefinition())
114 llvm::Constant *GetAddrOfGlobal(
GlobalDecl global,
bool isForDefinition) {
115 return Builder->GetAddrOfGlobal(global, isForDefinition);
121 M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
122 M->setDataLayout(Ctx->getTargetInfo().getDataLayout());
124 PreprocessorOpts, CodeGenOpts,
125 *M, Diags, CoverageInfo));
127 for (
auto &&Lib : CodeGenOpts.DependentLibraries)
129 for (
auto &&Opt : CodeGenOpts.LinkerOptions)
130 Builder->AppendLinkerOptions(Opt);
133 void HandleCXXStaticMemberVarInstantiation(
VarDecl *VD)
override {
134 if (Diags.hasErrorOccurred())
137 Builder->HandleCXXStaticMemberVarInstantiation(VD);
141 if (Diags.hasErrorOccurred())
144 HandlingTopLevelDeclRAII HandlingDecl(*
this);
153 void EmitDeferredDecls() {
154 if (DeferredInlineMethodDefinitions.empty())
160 HandlingTopLevelDeclRAII HandlingDecl(*
this);
161 for (
unsigned I = 0;
I != DeferredInlineMethodDefinitions.size(); ++
I)
162 Builder->EmitTopLevelDecl(DeferredInlineMethodDefinitions[
I]);
163 DeferredInlineMethodDefinitions.clear();
166 void HandleInlineFunctionDefinition(
FunctionDecl *D)
override {
167 if (Diags.hasErrorOccurred())
173 if (D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)) {
174 if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()
181 auto MD = cast<CXXMethodDecl>(D);
191 DeferredInlineMethodDefinitions.push_back(MD);
196 if (!MD->getParent()->getDescribedClassTemplate())
197 Builder->AddDeferredUnusedCoverageMapping(MD);
204 void HandleTagDeclDefinition(
TagDecl *D)
override {
205 if (Diags.hasErrorOccurred())
210 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
212 Builder->UpdateCompletedType(D);
216 if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
218 if (
VarDecl *VD = dyn_cast<VarDecl>(Member)) {
219 if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
220 Ctx->DeclMustBeEmitted(VD)) {
227 if (Ctx->getLangOpts().OpenMP) {
229 if (
auto *DRD = dyn_cast<OMPDeclareReductionDecl>(Member)) {
230 if (Ctx->DeclMustBeEmitted(DRD))
237 void HandleTagDeclRequiredDefinition(
const TagDecl *D)
override {
238 if (Diags.hasErrorOccurred())
243 HandlingTopLevelDeclRAII HandlingDecl(*
this,
false);
246 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(D))
247 DI->completeRequiredType(RD);
250 void HandleTranslationUnit(
ASTContext &Ctx)
override {
252 if (!Diags.hasErrorOccurred() &&
Builder)
257 if (Diags.hasErrorOccurred()) {
266 if (Diags.hasErrorOccurred())
269 Builder->RefreshTypeCacheForClass(RD);
272 void CompleteTentativeDefinition(
VarDecl *D)
override {
273 if (Diags.hasErrorOccurred())
276 Builder->EmitTentativeDefinition(D);
280 if (Diags.hasErrorOccurred())
288 void CodeGenerator::anchor() { }
291 return static_cast<CodeGeneratorImpl*
>(
this)->CGM();
295 return static_cast<CodeGeneratorImpl*
>(
this)->GetModule();
299 return static_cast<CodeGeneratorImpl*
>(
this)->ReleaseModule();
303 return static_cast<CodeGeneratorImpl*
>(
this)->GetDeclForMangledName(name);
307 bool isForDefinition) {
308 return static_cast<CodeGeneratorImpl*
>(
this)
309 ->GetAddrOfGlobal(global, isForDefinition);
317 return new CodeGeneratorImpl(Diags, ModuleName, HeaderSearchOpts,
318 PreprocessorOpts, CGO, C, CoverageInfo);
Defines the clang::ASTContext interface.
llvm::Constant * GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition)
Return the LLVM address of the given global entity.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Stores additional source code information like skipped ranges which is required by the coverage mappi...
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
llvm::Module * ReleaseModule()
Release ownership of the module to the caller.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
GlobalDecl getCanonicalDecl() const
RecordDecl - Represents a struct/union/class.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const Decl * getDecl() const
Describes a module or submodule.
Concrete class used by the front-end to report problems and issues.
CodeGenerator * CreateLLVMCodeGen(DiagnosticsEngine &Diags, llvm::StringRef ModuleName, const HeaderSearchOptions &HeaderSearchOpts, const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO, llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo=nullptr)
CreateLLVMCodeGen - Create a CodeGenerator instance.
The primary public interface to the Clang code generator.
detail::InMemoryDirectory::const_iterator I
llvm::Module * GetModule()
Return the module that this code generator is building into.
The result type of a method or function.
GlobalDecl - represents a global declaration.
CodeGen::CodeGenModule & CGM()
Return an opaque reference to the CodeGenModule object, which can be used in various secondary APIs...
bool doesThisDeclarationHaveABody() const
doesThisDeclarationHaveABody - Returns whether this specific declaration of the function has a body -...
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...
TagDecl - Represents the declaration of a struct/union/class/enum.
This class organizes the cross-function state that is used while generating LLVM code.
detail::InMemoryDirectory::const_iterator E
Defines the Diagnostic-related interfaces.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
Represents a C++ struct/union/class.
BoundNodesTreeBuilder *const Builder
Defines the clang::TargetInfo interface.