#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"
#include "llvm/Config/config.h"
#include "llvm/ADT/OwningPtr.h"
#include <memory>
+#include <fstream>
using namespace clang;
//===----------------------------------------------------------------------===//
/// parsed from source files as well as those deserialized from Bitcode.
static ASTConsumer* CreateASTConsumer(const std::string& InFile,
Diagnostic& Diag, FileManager& FileMgr,
- const LangOptions& LangOpts) {
+ const LangOptions& LangOpts,
+ llvm::Module *&DestModule) {
switch (ProgAction) {
default:
return NULL;
return CreateSerializationTest(Diag, FileMgr, LangOpts);
case EmitLLVM:
- return CreateLLVMEmitter(Diag, LangOpts);
-
case EmitBC:
- return CreateBCWriter(InFile, OutputFile, Diag, LangOpts);
+ DestModule = new llvm::Module(InFile);
+ return CreateLLVMCodeGen(Diag, LangOpts, DestModule);
case SerializeAST:
// FIXME: Allow user to tailor where the file is written.
ASTConsumer* Consumer = NULL;
bool ClearSourceMgr = false;
+ llvm::Module *CodeGenModule = 0;
switch (ProgAction) {
default:
Consumer = CreateASTConsumer(InFile,
PP.getDiagnostics(),
PP.getFileManager(),
- PP.getLangOptions());
+ PP.getLangOptions(),
+ CodeGenModule);
if (!Consumer) {
fprintf(stderr, "Unexpected program action!\n");
// This deletes Consumer.
ParseAST(PP, Consumer, Stats);
}
+
+ // 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());
// 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->getLangOpts()));
+ Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOpts(),
+ DestModule));
if (!Consumer) {
fprintf(stderr, "Unsupported program action with serialized ASTs!\n");
Consumer->Initialize(*TU->getContext());
+ // FIXME: We need to inform Consumer about completed TagDecls as well.
for (TranslationUnit::iterator I=TU->begin(), E=TU->end(); I!=E; ++I)
Consumer->HandleTopLevelDecl(*I);
}