diff options
Diffstat (limited to 'clang/Driver')
-rw-r--r-- | clang/Driver/ASTConsumers.cpp | 76 | ||||
-rw-r--r-- | clang/Driver/ASTConsumers.h | 6 | ||||
-rw-r--r-- | clang/Driver/clang.cpp | 57 |
3 files changed, 87 insertions, 52 deletions
diff --git a/clang/Driver/ASTConsumers.cpp b/clang/Driver/ASTConsumers.cpp index efeb9be8929..4a2ef778a09 100644 --- a/clang/Driver/ASTConsumers.cpp +++ b/clang/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/clang/Driver/ASTConsumers.h b/clang/Driver/ASTConsumers.h index c3cadfdcec4..7cb4ffb2274 100644 --- a/clang/Driver/ASTConsumers.h +++ b/clang/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/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index cb4c5e4bba3..56389dfb693 100644 --- a/clang/Driver/clang.cpp +++ b/clang/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"); |