#include "clang/Analysis/Analyses/LiveVariables.h"
#include "clang/Analysis/LocalCheckers.h"
#include "llvm/Support/Streams.h"
+#include <fstream>
using namespace clang;
#include "llvm/Module.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Bitcode/ReaderWriter.h"
namespace {
- class LLVMEmitter : public ASTConsumer {
+ class CodeGenerator : public ASTConsumer {
Diagnostic &Diags;
- llvm::Module *M;
const llvm::TargetData *TD;
ASTContext *Ctx;
const LangOptions &Features;
+ protected:
+ llvm::Module *M;
CodeGen::CodeGenModule *Builder;
public:
- LLVMEmitter(Diagnostic &diags, const LangOptions &LO)
+ CodeGenerator(Diagnostic &diags, const LangOptions &LO)
: Diags(diags)
, Features(LO) {}
virtual void Initialize(ASTContext &Context) {
// << D->getName() << "'\n";
}
}
-
+ };
+}
+
+namespace {
+ class LLVMEmitter : public CodeGenerator {
+ public:
+ LLVMEmitter(Diagnostic &diags, const LangOptions &LO)
+ : CodeGenerator(diags,LO) {}
+
~LLVMEmitter() {
CodeGen::Terminate(Builder);
M->print(llvm::cout.stream());
delete M;
}
- };
-} // end anonymous namespace
+ };
+}
ASTConsumer *clang::CreateLLVMEmitter(Diagnostic &Diags,
const LangOptions &Features) {
return new LLVMEmitter(Diags, Features);
}
+namespace {
+ class BCWriter : public CodeGenerator {
+ public:
+ std::ostream& Out;
+
+ BCWriter(std::ostream* out, Diagnostic &diags, const LangOptions &LO)
+ : CodeGenerator(diags,LO)
+ , Out(*out) {}
+
+ ~BCWriter() {
+ CodeGen::Terminate(Builder);
+ llvm::WriteBitcodeToFile(M, Out);
+ delete M;
+ }
+ };
+}
+
+ASTConsumer *clang::CreateBCWriter(const std::string& InFile,
+ const std::string& OutputFile,
+ Diagnostic &Diags,
+ const LangOptions &Features) {
+ std::string FileName = OutputFile;
+ if (!OutputFile.size()) {
+ llvm::sys::Path Path(InFile);
+ Path.eraseSuffix();
+ Path.appendSuffix("bc");
+ FileName = Path.toString();
+ }
+
+ std::ofstream *Out = new std::ofstream(FileName.c_str());
+ return new BCWriter(Out, Diags, Features);
+}
+
//===----------------------------------------------------------------------===//
// AST Serializer
enum ProgActions {
RewriteTest, // Rewriter testing stuff.
EmitLLVM, // Emit a .ll file.
+ EmitBC, // Emit a .bc file.
SerializeAST, // Emit a .ast file.
ASTPrint, // Parse ASTs and print them.
ASTDump, // Parse ASTs and dump them.
"Run prototype serializtion code."),
clEnumValN(EmitLLVM, "emit-llvm",
"Build ASTs then convert to LLVM, emit .ll file"),
+ clEnumValN(EmitBC, "emit-llvm-bc",
+ "Build ASTs then convert to LLVM, emit .bc file"),
clEnumValN(SerializeAST, "serialize",
"Build ASTs and emit .ast file"),
clEnumValN(RewriteTest, "rewrite-test",
case EmitLLVM:
return CreateLLVMEmitter(Diag, LangOpts);
-
+
+ case EmitBC:
+ return CreateBCWriter(InFile, OutputFile, Diag, LangOpts);
+
case SerializeAST:
// FIXME: Allow user to tailor where the file is written.
return CreateASTSerializer(InFile, OutputFile, Diag, LangOpts);