diff options
Diffstat (limited to 'Driver/ASTConsumers.cpp')
-rw-r--r-- | Driver/ASTConsumers.cpp | 76 |
1 files changed, 76 insertions, 0 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); +} |