diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h b/clang/include/clang/CodeGen/ModuleBuilder.h index 4298ba06c472e..5173fd05d75d6 100644 --- a/clang/include/clang/CodeGen/ModuleBuilder.h +++ b/clang/include/clang/CodeGen/ModuleBuilder.h @@ -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 @@ class CodeGenerator : public ASTConsumer { /// /// It is illegal to call methods other than GetModule on the /// CodeGenerator after releasing its module. - llvm::Module *ReleaseModule(); + std::unique_ptr ReleaseModule(); /// Return debug info code generator. CodeGen::CGDebugInfo *getCGDebugInfo(); @@ -109,16 +111,20 @@ class CodeGenerator : public ASTConsumer { }; /// 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 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 +CreateLLVMCodeGen(const CompilerInstance &CI, llvm::StringRef ModuleName, + llvm::LLVMContext &C, + CoverageSourceInfo *CoverageInfo = nullptr); + +std::unique_ptr +CreateLLVMCodeGen(DiagnosticsEngine &Diags, llvm::StringRef ModuleName, + IntrusiveRefCntPtr 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 diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 60d6b7fa009e7..a5ef4ac9d361d 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -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; diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 8ec8aef311656..b4885d572c294 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -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 FS; // Only used for debug info. @@ -60,12 +61,8 @@ namespace { }; CoverageSourceInfo *CoverageInfo; - - protected: std::unique_ptr M; std::unique_ptr Builder; - - private: SmallVector 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 ReleaseModule() { + return std::exchange(M, nullptr); } const Decl *GetDeclForMangledName(StringRef MangledName) { @@ -143,6 +140,7 @@ namespace { std::unique_ptr 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(Member)) { @@ -341,7 +340,7 @@ llvm::Module *CodeGenerator::GetModule() { return static_cast(this)->GetModule(); } -llvm::Module *CodeGenerator::ReleaseModule() { +std::unique_ptr CodeGenerator::ReleaseModule() { return static_cast(this)->ReleaseModule(); } @@ -368,16 +367,26 @@ llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName, return static_cast(this)->StartModule(ModuleName, C); } -CodeGenerator * +std::unique_ptr clang::CreateLLVMCodeGen(DiagnosticsEngine &Diags, llvm::StringRef ModuleName, IntrusiveRefCntPtr 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(Diags, ModuleName, std::move(FS), + HeaderSearchOpts, PreprocessorOpts, + CGO, C, CoverageInfo); +} + +std::unique_ptr +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 { diff --git a/clang/tools/clang-import-test/clang-import-test.cpp b/clang/tools/clang-import-test/clang-import-test.cpp index 977cec1d53157..8e83687d3e96a 100644 --- a/clang/tools/clang-import-test/clang-import-test.cpp +++ b/clang/tools/clang-import-test/clang-import-test.cpp @@ -235,10 +235,7 @@ BuildASTContext(CompilerInstance &CI, SelectorTable &ST, Builtin::Context &BC) { std::unique_ptr BuildCodeGen(CompilerInstance &CI, llvm::LLVMContext &LLVMCtx) { StringRef ModuleName("$__module"); - return std::unique_ptr(CreateLLVMCodeGen( - CI.getDiagnostics(), ModuleName, CI.getVirtualFileSystemPtr(), - CI.getHeaderSearchOpts(), CI.getPreprocessorOpts(), CI.getCodeGenOpts(), - LLVMCtx)); + return CreateLLVMCodeGen(CI, ModuleName, LLVMCtx); } } // namespace init_convenience diff --git a/clang/unittests/CodeGen/TestCompiler.h b/clang/unittests/CodeGen/TestCompiler.h index 9bd90609fcd29..18947584bd0b3 100644 --- a/clang/unittests/CodeGen/TestCompiler.h +++ b/clang/unittests/CodeGen/TestCompiler.h @@ -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, diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp index bae3c44e333b6..25259cd4bdcf5 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp @@ -874,11 +874,8 @@ ClangExpressionParser::ClangExpressionParser( std::string module_name("$__lldb_module"); m_llvm_context = std::make_unique(); - 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;