diff options
author | Chris Lattner <sabre@nondot.org> | 2008-02-06 01:42:25 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-02-06 01:42:25 +0000 |
commit | b5eda6253b28dd2669bda220b455d05c5e99796a (patch) | |
tree | 71a848afaf9ee41fd8a32d5443d0cde19d569d7a /clang/Driver/clang.cpp | |
parent | 182a9fd39f7a1faadef69a65818f98531de19a6d (diff) | |
download | bcm5719-llvm-b5eda6253b28dd2669bda220b455d05c5e99796a.tar.gz bcm5719-llvm-b5eda6253b28dd2669bda220b455d05c5e99796a.zip |
pull .ll and .bc writing out of the ASTConsumer destructors into some top
level code in clang. This is a cleanup, but does implement "-o" for
-emit-llvm. One effect of this is that "clang foo.c -emit-llvm" will now
emit into foo.ll instead of stdout. Use "clang foo.c -emit-llvm -o -" or
"clang < foo.c -emit-llvm" to get the old behavior.
llvm-svn: 46791
Diffstat (limited to 'clang/Driver/clang.cpp')
-rw-r--r-- | clang/Driver/clang.cpp | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index 3aabdc312cb..6e76a4a0cd2 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -34,13 +34,16 @@ #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; //===----------------------------------------------------------------------===// @@ -930,7 +933,8 @@ static void ParseFile(Preprocessor &PP, MinimalAction *PA){ /// 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; @@ -964,10 +968,9 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile, 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. @@ -985,13 +988,15 @@ static void ProcessInputFile(Preprocessor &PP, const std::string &InFile, 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"); @@ -1050,6 +1055,41 @@ static void ProcessInputFile(Preprocessor &PP, const std::string &InFile, // 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()); @@ -1093,8 +1133,10 @@ 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->getLangOpts())); + Consumer(CreateASTConsumer(InFile, Diag, FileMgr, TU->getLangOpts(), + DestModule)); if (!Consumer) { fprintf(stderr, "Unsupported program action with serialized ASTs!\n"); @@ -1103,6 +1145,7 @@ static void ProcessSerializedFile(const std::string& InFile, Diagnostic& Diag, 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); } |