[Clang] Improve CodeGenerator API a bit (#175239)
Essentially, figuring out how to use `CodeGenerator` was very confusing to me and I figured the API could be improved a bit, so: - the `CodeGenerator` ctor is now protected since an instance of `CodeGenerator` that is not a `CodeGeneratorImpl` is a bit useless (and deriving from it and implementing it yourself honestly just defeats the point of using this to begin with); - `ReleaseModule()` releases ownership of the module, so it should return a `unique_ptr`; - `CreateLLVMCodeGen()` also returns a `unique_ptr` now; - added a `CreateLLVMCodeGen()` overload that takes a `CompilerInstance&` and uses some of its state instead of requiring the user to pass everything in manually; this is consistent w/ other parts of our API, and most uses of this function in the codebase can be refactored to use that overload instead (and a code search I did also showed that a lot of people that use this API also just use the state from a `CompilerInstance`). I should have liked to replace `CreateLLVMCodeGen` w/ `CodeGenerator::Create`, but there are a lot of uses of `CreateLLVMCodeGen()` in the wild, so the only thing we could do is keep `CreateLLVMCodeGen()` and deprecate it, and at that point I don’t think it’s really worth it; I added a comment to the `CodeGenerator()` constructor declaration that points to it though. Fixes #172169.
This commit is contained in:
parent
a062249932
commit
62c97aa519
@ -40,6 +40,7 @@ namespace clang {
|
||||
class HeaderSearchOptions;
|
||||
class LangOptions;
|
||||
class PreprocessorOptions;
|
||||
class CompilerInstance;
|
||||
|
||||
namespace CodeGen {
|
||||
class CodeGenModule;
|
||||
@ -47,12 +48,13 @@ namespace CodeGen {
|
||||
}
|
||||
|
||||
/// The primary public interface to the Clang code generator.
|
||||
///
|
||||
/// This is not really an abstract interface.
|
||||
class CodeGenerator : public ASTConsumer {
|
||||
virtual void anchor();
|
||||
|
||||
protected:
|
||||
/// Use CreateLLVMCodeGen() below to create an instance of this class.
|
||||
CodeGenerator() = default;
|
||||
|
||||
/// True if we've finished generating IR. This prevents us from generating
|
||||
/// additional LLVM IR after emitting output in HandleTranslationUnit. This
|
||||
/// can happen when Clang plugins trigger additional AST deserialization.
|
||||
@ -78,7 +80,7 @@ public:
|
||||
///
|
||||
/// It is illegal to call methods other than GetModule on the
|
||||
/// CodeGenerator after releasing its module.
|
||||
llvm::Module *ReleaseModule();
|
||||
std::unique_ptr<llvm::Module> ReleaseModule();
|
||||
|
||||
/// Return debug info code generator.
|
||||
CodeGen::CGDebugInfo *getCGDebugInfo();
|
||||
@ -109,16 +111,20 @@ public:
|
||||
};
|
||||
|
||||
/// CreateLLVMCodeGen - Create a CodeGenerator instance.
|
||||
/// It is the responsibility of the caller to call delete on
|
||||
/// the allocated CodeGenerator instance.
|
||||
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);
|
||||
///
|
||||
/// Remember to call Initialize() if you plan to use this directly.
|
||||
std::unique_ptr<CodeGenerator>
|
||||
CreateLLVMCodeGen(const CompilerInstance &CI, llvm::StringRef ModuleName,
|
||||
llvm::LLVMContext &C,
|
||||
CoverageSourceInfo *CoverageInfo = nullptr);
|
||||
|
||||
std::unique_ptr<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);
|
||||
|
||||
namespace CodeGen {
|
||||
/// Demangle the artificial function name (\param FuncName) used to encode trap
|
||||
|
||||
@ -118,9 +118,7 @@ BackendConsumer::BackendConsumer(CompilerInstance &CI, BackendAction Action,
|
||||
: CI(CI), Diags(CI.getDiagnostics()), CodeGenOpts(CI.getCodeGenOpts()),
|
||||
TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
|
||||
AsmOutStream(std::move(OS)), FS(VFS), Action(Action),
|
||||
Gen(CreateLLVMCodeGen(Diags, InFile, std::move(VFS),
|
||||
CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(),
|
||||
CI.getCodeGenOpts(), C, CoverageInfo)),
|
||||
Gen(CreateLLVMCodeGen(CI, InFile, C, CoverageInfo)),
|
||||
LinkModules(std::move(LinkModules)), CurLinkModule(CurLinkModule) {
|
||||
TimerIsEnabled = CodeGenOpts.TimePasses;
|
||||
llvm::TimePassesIsEnabled = CodeGenOpts.TimePasses;
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
#include "clang/Basic/CodeGenOptions.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/TargetInfo.h"
|
||||
#include "clang/Frontend/CompilerInstance.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
@ -31,7 +32,7 @@ using namespace clang;
|
||||
using namespace CodeGen;
|
||||
|
||||
namespace {
|
||||
class CodeGeneratorImpl : public CodeGenerator {
|
||||
class CodeGeneratorImpl final : public CodeGenerator {
|
||||
DiagnosticsEngine &Diags;
|
||||
ASTContext *Ctx;
|
||||
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; // Only used for debug info.
|
||||
@ -60,12 +61,8 @@ namespace {
|
||||
};
|
||||
|
||||
CoverageSourceInfo *CoverageInfo;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<llvm::Module> M;
|
||||
std::unique_ptr<CodeGen::CodeGenModule> Builder;
|
||||
|
||||
private:
|
||||
SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
|
||||
|
||||
static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
|
||||
@ -107,8 +104,8 @@ namespace {
|
||||
return Builder->getModuleDebugInfo();
|
||||
}
|
||||
|
||||
llvm::Module *ReleaseModule() {
|
||||
return M.release();
|
||||
std::unique_ptr<llvm::Module> ReleaseModule() {
|
||||
return std::exchange(M, nullptr);
|
||||
}
|
||||
|
||||
const Decl *GetDeclForMangledName(StringRef MangledName) {
|
||||
@ -143,6 +140,7 @@ namespace {
|
||||
|
||||
std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
|
||||
|
||||
assert(Ctx && "must call Initialize() before calling StartModule()");
|
||||
Initialize(*Ctx);
|
||||
|
||||
if (OldBuilder)
|
||||
@ -251,6 +249,7 @@ namespace {
|
||||
|
||||
// For MSVC compatibility, treat declarations of static data members with
|
||||
// inline initializers as definitions.
|
||||
assert(Ctx && "Initialize() not called");
|
||||
if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
|
||||
for (Decl *Member : D->decls()) {
|
||||
if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
|
||||
@ -341,7 +340,7 @@ llvm::Module *CodeGenerator::GetModule() {
|
||||
return static_cast<CodeGeneratorImpl*>(this)->GetModule();
|
||||
}
|
||||
|
||||
llvm::Module *CodeGenerator::ReleaseModule() {
|
||||
std::unique_ptr<llvm::Module> CodeGenerator::ReleaseModule() {
|
||||
return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
|
||||
}
|
||||
|
||||
@ -368,16 +367,26 @@ llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName,
|
||||
return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);
|
||||
}
|
||||
|
||||
CodeGenerator *
|
||||
std::unique_ptr<CodeGenerator>
|
||||
clang::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) {
|
||||
return new CodeGeneratorImpl(Diags, ModuleName, std::move(FS),
|
||||
HeaderSearchOpts, PreprocessorOpts, CGO, C,
|
||||
CoverageInfo);
|
||||
return std::make_unique<CodeGeneratorImpl>(Diags, ModuleName, std::move(FS),
|
||||
HeaderSearchOpts, PreprocessorOpts,
|
||||
CGO, C, CoverageInfo);
|
||||
}
|
||||
|
||||
std::unique_ptr<CodeGenerator>
|
||||
clang::CreateLLVMCodeGen(const CompilerInstance &CI, StringRef ModuleName,
|
||||
llvm::LLVMContext &C,
|
||||
CoverageSourceInfo *CoverageInfo) {
|
||||
return CreateLLVMCodeGen(CI.getDiagnostics(), ModuleName,
|
||||
CI.getVirtualFileSystemPtr(),
|
||||
CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(),
|
||||
CI.getCodeGenOpts(), C, CoverageInfo);
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -235,10 +235,7 @@ BuildASTContext(CompilerInstance &CI, SelectorTable &ST, Builtin::Context &BC) {
|
||||
std::unique_ptr<CodeGenerator> BuildCodeGen(CompilerInstance &CI,
|
||||
llvm::LLVMContext &LLVMCtx) {
|
||||
StringRef ModuleName("$__module");
|
||||
return std::unique_ptr<CodeGenerator>(CreateLLVMCodeGen(
|
||||
CI.getDiagnostics(), ModuleName, CI.getVirtualFileSystemPtr(),
|
||||
CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), CI.getCodeGenOpts(),
|
||||
LLVMCtx));
|
||||
return CreateLLVMCodeGen(CI, ModuleName, LLVMCtx);
|
||||
}
|
||||
} // namespace init_convenience
|
||||
|
||||
|
||||
@ -57,10 +57,7 @@ struct TestCompiler {
|
||||
|
||||
compiler.createASTContext();
|
||||
|
||||
CG.reset(CreateLLVMCodeGen(
|
||||
compiler.getDiagnostics(), "main-module",
|
||||
compiler.getVirtualFileSystemPtr(), compiler.getHeaderSearchOpts(),
|
||||
compiler.getPreprocessorOpts(), compiler.getCodeGenOpts(), Context));
|
||||
CG = CreateLLVMCodeGen(compiler, "main-module", Context);
|
||||
}
|
||||
|
||||
void init(const char *TestProgram,
|
||||
|
||||
@ -880,11 +880,8 @@ ClangExpressionParser::ClangExpressionParser(
|
||||
std::string module_name("$__lldb_module");
|
||||
|
||||
m_llvm_context = std::make_unique<LLVMContext>();
|
||||
m_code_generator.reset(CreateLLVMCodeGen(
|
||||
m_compiler->getDiagnostics(), module_name,
|
||||
m_compiler->getVirtualFileSystemPtr(), m_compiler->getHeaderSearchOpts(),
|
||||
m_compiler->getPreprocessorOpts(), m_compiler->getCodeGenOpts(),
|
||||
*m_llvm_context));
|
||||
m_code_generator =
|
||||
CreateLLVMCodeGen(*m_compiler, module_name, *m_llvm_context);
|
||||
}
|
||||
|
||||
ClangExpressionParser::~ClangExpressionParser() = default;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user