diff options
-rw-r--r-- | Driver/ASTConsumers.cpp | 76 | ||||
-rw-r--r-- | Driver/ASTConsumers.h | 6 | ||||
-rw-r--r-- | Driver/clang.cpp | 57 | ||||
-rw-r--r-- | include/clang/CodeGen/ModuleBuilder.h | 16 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 12 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 9 | ||||
-rw-r--r-- | lib/CodeGen/ModuleBuilder.cpp | 49 |
7 files changed, 141 insertions, 84 deletions
diff --git a/Driver/ASTConsumers.cpp b/Driver/ASTConsumers.cpp index efeb9be892..4a2ef778a0 100644 --- a/Driver/ASTConsumers.cpp +++ b/Driver/ASTConsumers.cpp @@ -18,9 +18,13 @@ #include "clang/Basic/FileManager.h" #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" +#include "clang/CodeGen/ModuleBuilder.h" +#include "llvm/Module.h" +#include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Support/Streams.h" #include "llvm/Support/Timer.h" #include "llvm/ADT/OwningPtr.h" +#include <fstream> using namespace clang; @@ -631,3 +635,75 @@ ASTConsumer* clang::CreateASTSerializer(const std::string& InFile, FName.appendSuffix("ast"); return new SingleFileSerializer(FName); } + +class LLVMCodeGenWriter : public ASTConsumer { + llvm::OwningPtr<CodeGenerator> Gen; + const std::string &InFile; + const std::string &OutputFile; + bool EmitBitcode; +public: + + LLVMCodeGenWriter(bool EmitBC, Diagnostic &Diags, const LangOptions &Features, + const std::string& infile, const std::string& outfile, + bool GenerateDebugInfo) + : Gen(CreateLLVMCodeGen(Diags, Features, infile, GenerateDebugInfo)), + InFile(infile), OutputFile(outfile), EmitBitcode(EmitBC) {} + + virtual void Initialize(ASTContext &Context) { + Gen->Initialize(Context); + } + + virtual void HandleTopLevelDecl(Decl *D) { + Gen->HandleTopLevelDecl(D); + } + + virtual void HandleTagDeclDefinition(TagDecl *D) { + Gen->HandleTagDeclDefinition(D); + } + + virtual ~LLVMCodeGenWriter() { + llvm::OwningPtr<llvm::Module> CodeGenModule(Gen->ReleaseModule()); + + if (!CodeGenModule) + return; + + std::ostream *Out; + + if (OutputFile == "-") { + Out = llvm::cout.stream(); + } else if (!OutputFile.empty()) { + Out = new std::ofstream(OutputFile.c_str(), + std::ios_base::binary|std::ios_base::out); + } else if (InFile == "-") { + Out = llvm::cout.stream(); + } else { + llvm::sys::Path Path(InFile); + Path.eraseSuffix(); + if (!EmitBitcode) + Path.appendSuffix("ll"); + else + Path.appendSuffix("bc"); + + Out = new std::ofstream(Path.toString().c_str(), + std::ios_base::binary|std::ios_base::out); + } + + if (!EmitBitcode) + CodeGenModule->print(*Out); + else + llvm::WriteBitcodeToFile(CodeGenModule.get(), *Out); + + if (Out != llvm::cout.stream()) + delete Out; + } +}; + +ASTConsumer *clang::CreateLLVMCodeGenWriter(bool EmitBC, Diagnostic &Diags, + const LangOptions &Features, + const std::string& InFile, + const std::string& OutFile, + bool GenerateDebugInfo) { + + return new LLVMCodeGenWriter(EmitBC, Diags, Features, InFile, OutFile, + GenerateDebugInfo); +} diff --git a/Driver/ASTConsumers.h b/Driver/ASTConsumers.h index c3cadfdcec..7cb4ffb227 100644 --- a/Driver/ASTConsumers.h +++ b/Driver/ASTConsumers.h @@ -40,6 +40,12 @@ ASTConsumer *CreateCodeRewriterTest(const std::string& InFile, const std::string& OutFile, Diagnostic &Diags, const LangOptions &LOpts); + +ASTConsumer *CreateLLVMCodeGenWriter(bool EmitBC, Diagnostic &Diags, + const LangOptions &Features, + const std::string& InFile, + const std::string& OutFile, + bool GenerateDebugInfo); ASTConsumer* CreateHTMLPrinter(const std::string &OutFile, Diagnostic &D, Preprocessor *PP, PreprocessorFactory* PPF); diff --git a/Driver/clang.cpp b/Driver/clang.cpp index cb4c5e4bba..56389dfb69 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -37,9 +37,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" -#include "llvm/Module.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/System/Signals.h" @@ -47,7 +45,6 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/System/Path.h" #include <memory> -#include <fstream> #include <algorithm> using namespace clang; @@ -1174,8 +1171,7 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile, Diagnostic& Diag, FileManager& FileMgr, const LangOptions& LangOpts, Preprocessor *PP, - PreprocessorFactory *PPF, - llvm::Module *&DestModule) { + PreprocessorFactory *PPF) { switch (ProgAction) { default: return NULL; @@ -1197,8 +1193,8 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile, case EmitLLVM: case EmitBC: - DestModule = new llvm::Module(InFile); - return CreateLLVMCodeGen(Diag, LangOpts, DestModule, GenerateDebugInfo); + return CreateLLVMCodeGenWriter(ProgAction == EmitBC, Diag, LangOpts, + InFile, OutputFile, GenerateDebugInfo); case SerializeAST: // FIXME: Allow user to tailor where the file is written. @@ -1225,13 +1221,12 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, ASTConsumer* Consumer = NULL; bool ClearSourceMgr = false; - llvm::Module *CodeGenModule = 0; switch (ProgAction) { default: Consumer = CreateASTConsumer(InFile, PP.getDiagnostics(), PP.getFileManager(), PP.getLangOptions(), &PP, - &PPF, CodeGenModule); + &PPF); if (!Consumer) { fprintf(stderr, "Unexpected program action!\n"); @@ -1296,47 +1291,6 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF, ParseAST(PP, Consumer, Stats); } - // Don't emit code when the input had errors. - if (CodeGenModule && PP.getDiagnostics().hasErrorOccurred()) { - delete CodeGenModule; - CodeGenModule = 0; - } - - // If running the code generator, finish up now. - if (CodeGenModule) { - std::ostream *Out; - if (OutputFile == "-") { - Out = llvm::cout.stream(); - } else if (!OutputFile.empty()) { - Out = new std::ofstream(OutputFile.c_str(), - std::ios_base::binary|std::ios_base::out); - } else if (InFile == "-") { - Out = llvm::cout.stream(); - } else { - llvm::sys::Path Path(InFile); - Path.eraseSuffix(); - if (ProgAction == EmitLLVM) - Path.appendSuffix("ll"); - else if (ProgAction == EmitBC) - Path.appendSuffix("bc"); - else - assert(0 && "Unknown action"); - Out = new std::ofstream(Path.toString().c_str(), - std::ios_base::binary|std::ios_base::out); - } - - if (ProgAction == EmitLLVM) { - CodeGenModule->print(*Out); - } else { - assert(ProgAction == EmitBC); - llvm::WriteBitcodeToFile(CodeGenModule, *Out); - } - - if (Out != llvm::cout.stream()) - delete Out; - delete CodeGenModule; - } - if (Stats) { fprintf(stderr, "\nSTATISTICS FOR '%s':\n", InFile.c_str()); PP.PrintStats(); @@ -1379,10 +1333,9 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag, // Observe that we use the source file name stored in the deserialized // translation unit, rather than InFile. - llvm::Module *DestModule; llvm::OwningPtr<ASTConsumer> Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOptions(), - 0, 0, DestModule)); + 0, 0)); if (!Consumer) { fprintf(stderr, "Unsupported program action with serialized ASTs!\n"); diff --git a/include/clang/CodeGen/ModuleBuilder.h b/include/clang/CodeGen/ModuleBuilder.h index b6ec1cf142..0f9b39341b 100644 --- a/include/clang/CodeGen/ModuleBuilder.h +++ b/include/clang/CodeGen/ModuleBuilder.h @@ -14,6 +14,9 @@ #ifndef LLVM_CLANG_CODEGEN_MODULEBUILDER_H #define LLVM_CLANG_CODEGEN_MODULEBUILDER_H +#include "clang/AST/ASTConsumer.h" +#include <string> + namespace llvm { class Module; } @@ -21,11 +24,16 @@ namespace llvm { namespace clang { class Diagnostic; struct LangOptions; - class ASTConsumer; - ASTConsumer *CreateLLVMCodeGen(Diagnostic &Diags, const LangOptions &Features, - llvm::Module *&DestModule, - bool GenerateDebugInfo); + class CodeGenerator : public ASTConsumer { + public: + virtual llvm::Module* ReleaseModule() = 0; + }; + + CodeGenerator *CreateLLVMCodeGen(Diagnostic &Diags, + const LangOptions &Features, + const std::string& ModuleName, + bool GenerateDebugInfo); } #endif diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 5d85b7a70f..0c3b872b9a 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -42,13 +42,15 @@ CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO, Runtime = CreateObjCRuntime(*this); // If debug info generation is enabled, create the CGDebugInfo object. - if (GenerateDebugInfo) - DebugInfo = new CGDebugInfo(this); - else - DebugInfo = NULL; + DebugInfo = GenerateDebugInfo ? new CGDebugInfo(this) : 0; } CodeGenModule::~CodeGenModule() { + delete Runtime; + delete DebugInfo; +} + +void CodeGenModule::Release() { EmitStatics(); llvm::Function *ObjCInitFunction = Runtime->ModuleInitFunction(); if (ObjCInitFunction) @@ -56,8 +58,6 @@ CodeGenModule::~CodeGenModule() { EmitCtorList(GlobalCtors, "llvm.global_ctors"); EmitCtorList(GlobalDtors, "llvm.global_dtors"); EmitAnnotations(); - delete Runtime; - delete DebugInfo; // Run the verifier to check that the generated code is consistent. assert(!verifyModule(TheModule)); } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 1fb2cf7ae0..bb5de154fb 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -19,6 +19,7 @@ #include "clang/AST/Attr.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/OwningPtr.h" namespace llvm { class Module; @@ -62,8 +63,8 @@ class CodeGenModule { const llvm::TargetData &TheTargetData; Diagnostic &Diags; CodeGenTypes Types; - CGObjCRuntime *Runtime; - CGDebugInfo *DebugInfo; + CGObjCRuntime* Runtime; + CGDebugInfo* DebugInfo; llvm::Function *MemCpyFn; llvm::Function *MemMoveFn; @@ -103,8 +104,12 @@ public: CodeGenModule(ASTContext &C, const LangOptions &Features, llvm::Module &M, const llvm::TargetData &TD, Diagnostic &Diags, bool GenerateDebugInfo); + ~CodeGenModule(); + /// Release - Finalize LLVM code generation. + void Release(); + CGObjCRuntime *getObjCRuntime() { return Runtime; } CGDebugInfo *getDebugInfo() { return DebugInfo; } ASTContext &getContext() const { return Context; } diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index 201092f4d8..7329ed1d90 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -13,7 +13,6 @@ #include "clang/CodeGen/ModuleBuilder.h" #include "CodeGenModule.h" -#include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" using namespace clang; @@ -27,26 +26,37 @@ using namespace clang; #include "llvm/Module.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Support/Compiler.h" +#include "llvm/ADT/OwningPtr.h" + namespace { - class CodeGenerator : public ASTConsumer { + class VISIBILITY_HIDDEN CodeGeneratorImpl : public CodeGenerator { Diagnostic &Diags; - const llvm::TargetData *TD; + llvm::OwningPtr<const llvm::TargetData> TD; ASTContext *Ctx; const LangOptions &Features; bool GenerateDebugInfo; protected: - llvm::Module *&M; - CodeGen::CodeGenModule *Builder; + llvm::OwningPtr<llvm::Module> M; + llvm::OwningPtr<CodeGen::CodeGenModule> Builder; public: - CodeGenerator(Diagnostic &diags, const LangOptions &LO, - llvm::Module *&DestModule, bool DebugInfoFlag) + CodeGeneratorImpl(Diagnostic &diags, const LangOptions &LO, + const std::string& ModuleName, + bool DebugInfoFlag) : Diags(diags), Features(LO), GenerateDebugInfo(DebugInfoFlag), - M(DestModule) {} + M(new llvm::Module(ModuleName)) {} + + virtual ~CodeGeneratorImpl() {} - ~CodeGenerator() { - delete Builder; - delete TD; + virtual llvm::Module* ReleaseModule() { + if (Diags.hasErrorOccurred()) + return 0; + + if (Builder) + Builder->Release(); + + return M.take(); } virtual void Initialize(ASTContext &Context) { @@ -54,9 +64,9 @@ namespace { M->setTargetTriple(Ctx->Target.getTargetTriple()); M->setDataLayout(Ctx->Target.getTargetDescription()); - TD = new llvm::TargetData(Ctx->Target.getTargetDescription()); - Builder = new CodeGen::CodeGenModule(Context, Features, *M, *TD, Diags, - GenerateDebugInfo); + TD.reset(new llvm::TargetData(Ctx->Target.getTargetDescription())); + Builder.reset(new CodeGen::CodeGenModule(Context, Features, *M, *TD, + Diags, GenerateDebugInfo)); } virtual void HandleTopLevelDecl(Decl *D) { @@ -128,10 +138,9 @@ namespace { }; } -ASTConsumer *clang::CreateLLVMCodeGen(Diagnostic &Diags, - const LangOptions &Features, - llvm::Module *&DestModule, - bool GenerateDebugInfo) { - return new CodeGenerator(Diags, Features, DestModule, GenerateDebugInfo); +CodeGenerator *clang::CreateLLVMCodeGen(Diagnostic &Diags, + const LangOptions &Features, + const std::string& ModuleName, + bool GenerateDebugInfo) { + return new CodeGeneratorImpl(Diags, Features, ModuleName, GenerateDebugInfo); } - |